Package dependencies
You can load them using the following code which uses a function called ipak. Note this function checks to see if the packages are installed first.
packages <- c("tidyr", "rJava", "dismo")
source("../src/ipak.R")
ipak(packages)
tidyr rJava dismo
TRUE TRUE TRUE
suppressMessages(ipak)
function(pkg){
new.pkg <- pkg[!(pkg %in% installed.packages()[, "Package"])]
if (length(new.pkg))
install.packages(new.pkg, dependencies = TRUE)
sapply(pkg, require, character.only = TRUE)
}
write.csv(asclayerall, "../data/env/asc_stacklist.csv", header = TRUE)
Error in write.table(asclayerall, "../data/env/asc_stacklist.csv", header = TRUE, :
unused argument (header = TRUE)
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 1998)
ascname <- list.files("../data/env/ascii/ascii1998/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii1998/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist1998.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCLAYER ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 1999)
ascname <- list.files("../data/env/ascii/ascii1999/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii1999/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist1999.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2000)
ascname <- list.files("../data/env/ascii/ascii2000/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2000/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2000.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2001)
ascname <- list.files("../data/env/ascii/ascii2001/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2001/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2001.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2002)
ascname <- list.files("../data/env/ascii/ascii2002/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2002/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2002.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2003)
ascname <- list.files("../data/env/ascii/ascii2003/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2003/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2003.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2004)
ascname <- list.files("../data/env/ascii/ascii2004/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2004/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2004.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2005)
ascname <- list.files("../data/env/ascii/ascii2005/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2005/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2005.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2006)
ascname <- list.files("../data/env/ascii/ascii2006/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2006/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2006.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2007)
ascname <- list.files("../data/env/ascii/ascii2007/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2007/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2007.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2008)
ascname <- list.files("../data/env/ascii/ascii2008/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2008/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2008.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2009)
ascname <- list.files("../data/env/ascii/ascii2009/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2009/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2009.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2010)
ascname <- list.files("../data/env/ascii/ascii2010/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2010/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2010.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2011)
ascname <- list.files("../data/env/ascii/ascii2011/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2011/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2011.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2012)
ascname <- list.files("../data/env/ascii/ascii2012/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2012/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2012.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2013)
ascname <- list.files("../data/env/ascii/ascii2013/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2013/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2013.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2014)
ascname <- list.files("../data/env/ascii/ascii2014/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2014/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2014.csv", row.names = TRUE)
}
#!!!!!! CHANGE ASCNAME, ASCPATH AND CSV FILE NAME
asclayer <- subset(asclayerall, ascyears == 2015)
ascname <- list.files("../data/env/ascii/ascii2015/", pattern = "*.asc", full.names = FALSE) # this folder currently contains other dummy files. its just a test to automate stacks
ascpath <- list.files("../data/env/ascii/ascii2015/", pattern = "*.asc", full.names = TRUE) # this folder currently contains other dummy files. its just a test to automate stacks
tempvar <- "temp.nc"
chlvar <- "chl.nc"
o2var <- "o2.nc"
salvar <- "salinity.nc"
mlpvar <- "mlp.nc"
sshvar <- "ssh.nc"
naosamplevar <- "naosample"
amosamplevar <- "amosample"
naoprevvar <- "naoprev"
amoprevvar <- "amoprev"
naowintervar <- "naowinter"
amowintervar <- "amowinter"
surfacevar <- "0.50576"
for (i in 1:nrow(asclayer)){
print(asclayer$stackname[i])
year <- asclayer$ascyears[i]
month <- asclayer$ascmonths[i]
depth <- asclayer$ascdepths[i]
for (k in 1:length(ascname)){
ascyear <- (sapply(strsplit(ascname[k], "_"), "[[", 1))
ascmonth <- (sapply(strsplit(ascname[k], "_"), "[[", 2))
ascvar <- (sapply(strsplit(ascname[k], "_"), "[[", 3))
ascdepth <- (sapply(strsplit(ascname[k], "_"), "[[", 4))
ascdepth <- gsub(".asc", "", ascdepth)
ascfile <- ascpath[k]
if (ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == depth){
asclayer$temp_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == tempvar & ascdepth == surfacevar){
asclayer$temp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == depth){
asclayer$salinity_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == salvar & ascdepth == surfacevar){
asclayer$salinity_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == depth){
asclayer$chl_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == chlvar & ascdepth == surfacevar){
asclayer$chl_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == depth){
asclayer$o2_depth[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == o2var & ascdepth == surfacevar){
asclayer$o2_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == mlpvar){
asclayer$mlp_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == sshvar){
asclayer$ssh_surface[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naosamplevar){
asclayer$nao_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amosamplevar){
asclayer$amo_sample[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == naoprevvar){
asclayer$nao_prev[i] <- ascfile
} else if(ascyear == year & ascmonth == month & ascvar == amoprevvar){
asclayer$amo_prev[i] <- ascfile
} else if(ascyear == year & ascvar == naowintervar){
asclayer$nao_winter[i] <- ascfile
} else if(ascyear == year & ascvar == amowintervar){
asclayer$amo_winter[i] <- ascfile
}
}
write.csv(asclayer, "../data/env/asc_layerlist2015.csv", row.names = TRUE)
}
it may be better to have ascii lists per month (since models are per month)
split(as, as$ascmonths)
$`1`
$`2`
$`3`
$`4`
$`5`
$`6`
$`7`
$`8`
$`9`
$`10`
$`11`
$`12`
NA
LS0tDQp0aXRsZTogImFzY19maWxlX2RhdGFiYXNlIg0KYXV0aG9yOiAiU2FtYW50aGEgQW5kcmV3cyINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCiMgT3ZlcnZpZXcNClByZXBlcmF0aW9uIGRhdGFiYXNlIHRvIGV4dHJhY3QgYW5kIHN0YWNrIGFzYyBmaWxlcyANCg0KQSBub3RlIHRvIGFueW9uZSB3aG8gbWlnaHQgaGFwcGVuIHRvIHN0dW1ibGUgYWNyb3NzIHRoaXMuLi4gSSBhbSBhIGJlZ2lubmVyIGluIFIgYW5kIGhhdmUgaGFkIG5vIGV4cG9zdXJlIHRvIHNpbWlsYXIgbGFuZ3VhZ2VzLiBJIGRvbid0IGtub3cgd2hhdCBJJ20gZG9pbmcuIFRoZSBjb2RlIGhlcmVpbiBpcyB1bmxpa2VseSB0byBiZSBlbGVnYW50IGFuZCB0aGVyZSBhcmUgcHJvYmFibHkgbW9yZSBlZmZpY2llbnQgd2F5cyBvZiBydW5uaW5nIHRoZSBjb2RlLg0KDQpCdWlsdCB3aXRoICdyIGdldFJ2ZXJzaW9uKCknLg0KDQojIFBhY2thZ2UgZGVwZW5kZW5jaWVzDQpZb3UgY2FuIGxvYWQgdGhlbSB1c2luZyB0aGUgZm9sbG93aW5nIGNvZGUgd2hpY2ggdXNlcyBhIGZ1bmN0aW9uIGNhbGxlZCBbaXBha10oaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vc3RldmVud29ydGhpbmd0b24vMzE3ODE2MykuIA0KTm90ZSB0aGlzIGZ1bmN0aW9uIGNoZWNrcyB0byBzZWUgaWYgdGhlIHBhY2thZ2VzIGFyZSBpbnN0YWxsZWQgZmlyc3QuDQoNCmBgYHtyIHByZS1pbnN0YWxsIHBhY2thZ2VzLCBtZXNzYWdlPUZBTFNFfQ0KcGFja2FnZXMgPC0gYygidGlkeXIiLCAickphdmEiLCAiZGlzbW8iKQ0Kc291cmNlKCIuLi9zcmMvaXBhay5SIikNCmlwYWsocGFja2FnZXMpDQpzdXBwcmVzc01lc3NhZ2VzKGlwYWspDQpgYGANCg0KDQpgYGB7ciBiYXNlIGxpc3Qgb3IgYXNjaWkgbGF5ZXJzfQ0KYXNjeWVhcnMgPC0gYXMuY2hhcmFjdGVyKGMoIjE5OTgiLCAiMTk5OSIsICIyMDAwIiwgIjIwMDEiLCAiMjAwMiIsICIyMDAzIiwgIjIwMDQiLCAiMjAwNSIsICIyMDA2IiwgIjIwMDciLCAiMjAwOCIsICIyMDA5IiwgIjIwMTAiLCAiMjAxMSIsICIyMDEyIiwgIjIwMTMiLCAiMjAxNCIsICIyMDE1IikpIA0KI3VueWVhcnMgPC0gcGFzdGUwKCJYIiwgdW55ZWFycykgI3RoaXMgYWRkcyBhbiBYIHRvIGVhY2ggeWVhciB0byBtYXRjaCB3aXRoIHJhc3RlciBuYW1pbmcNCmFzY21vbnRocyA8LSBjKCIwMSIsICIwMiIsICIwMyIsICIwNCIsICIwNSIsICIwNiIsICIwNyIsICIwOCIsICIwOSIsICIxMCIsICIxMSIsICIxMiIpDQphc2NkZXB0aHMgPC0gYygiMC41MDU3NiIsICIxLjU1NTg2IiwgIjIuNjY3NjgiLCAiMy44NTYyOCIgLCAiNS4xNDAzNiIsICI2LjU0MzAzIiwgIjguMDkyNTIiLCAiOS44MjI3NSIsICIxMS43NzM3IiAsICIxMy45OTEiLCAiMTYuNTI1MyIgLCAiMTkuNDI5OCIsICIyMi43NTc2IiwgIjI2LjU1ODMiLCAiMzAuODc0NiIsICIzNS43NDAyIiwgIjA0MS4xOCIsICI0Ny4yMTE5IiwgIjUzLjg1MDYiLCAiNjEuMTEyOCIgLCAiNjkuMDIxNyIgLCAiNzcuNjExMiIsICI4Ni45Mjk0IiwgIjk3LjA0MTMiLCAiMTA4LjAzIiwgIjAwMDEyMCIsICIxMzMuMDc2IiwgIjE0Ny40MDYiLCAiMTYzLjE2NSIgLCAiMTgwLjU1IiwgIjE5OS43OSIsICIyMjEuMTQxIiwgIjI0NC44OTEiICwgIjI3MS4zNTYiLCAiMzAwLjg4OCIsICIzMzMuODYzIiAsICIzNzAuNjg5IiwgIjQxMS43OTQiLCAiNDU3LjYyNiIsICI1MDguNjQiLCAiNTY1LjI5MiIsICI2MjguMDI2IiwgIjY5Ny4yNTkiLCAiNzczLjM2OCIsICI4NTYuNjc5IiwgIjk0Ny40NDgiLCAiMTA0NS44NSIsICIxMTUxLjk5IiwgIjEyNjUuODYiLCAiMTM4Ny4zOCIpIA0KI3RoaXMgZGVwdGggbGlzdCBpcyBiYXNlZCBvbiBob3cgdGhlIGZpbGVzIGFyZSBuYW1lZCB3aGVuIHNwbGl0IGludG8gZGVwdGggbGF5ZXJzLiBub3RlIHRoYXQgY2hsIGFuZCBvMiBoYXZlIGhhZCB0d28gbWlub3IgbmFtZSBjaGFuZ2VkIC0gMTYzLjE2NCB0byAxNjMuMTY1IGFuZCAzNzAuNjU4IHRvIDM3MC42NTksIHRvIG1hdGNoIGFsbCBsYXllcnMNCg0KYXNjbGF5ZXJhbGwgPC0gY3Jvc3NpbmcoYXNjeWVhcnMsIGFzY21vbnRocywgYXNjZGVwdGhzKQ0KYXNjbGF5ZXJhbGwkc3RhY2tuYW1lIDwtIHBhc3RlMCgic3QiLCBhc2NsYXllcmFsbCRhc2N5ZWFycywgYXNjbGF5ZXJhbGwkYXNjbW9udGhzLCBhc2NsYXllcmFsbCRhc2NkZXB0aHMpICN0aGlzIGNyZWF0ZXMgdGhlIG5hbWUgb2YgdGhlIHN0YWNrIHRoYXQgd2lsbCBiZSB1c2VkDQphc2NsYXllcmFsbCR0ZW1wX2RlcHRoIDwtIE5BDQphc2NsYXllcmFsbCR0ZW1wX3N1cmZhY2UgPC0gTkENCmFzY2xheWVyYWxsJGNobF9kZXB0aCA8LSBOQQ0KYXNjbGF5ZXJhbGwkY2hsX3N1cmZhY2UgPC0gTkENCmFzY2xheWVyYWxsJG8yX2RlcHRoIDwtIE5BDQphc2NsYXllcmFsbCRvMl9zdXJmYWNlIDwtIE5BDQphc2NsYXllcmFsbCRzYWxpbml0eV9kZXB0aCA8LSBOQQ0KYXNjbGF5ZXJhbGwkc2FsaW5pdHlfc3VyZmFjZSA8LSBOQQ0KYXNjbGF5ZXJhbGwkc3NoX3N1cmZhY2UgPC0gTkENCmFzY2xheWVyYWxsJG1scF9zdXJmYWNlIDwtIE5BDQphc2NsYXllcmFsbCRuYW9fc2FtcGxlIDwtIE5BDQphc2NsYXllcmFsbCRuYW9fcHJldiA8LSBOQQ0KYXNjbGF5ZXJhbGwkbmFvX3dpbnRlciA8LSBOQQ0KYXNjbGF5ZXJhbGwkYW1vX3NhbXBsZSA8LSBOQQ0KYXNjbGF5ZXJhbGwkYW1vX3ByZXYgPC0gTkENCmFzY2xheWVyYWxsJGFtb193aW50ZXIgPC0gTkENCg0Kd3JpdGUuY3N2KGFzY2xheWVyYWxsLCAiLi4vZGF0YS9lbnYvYXNjX3N0YWNrbGlzdC5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KDQoNCmBgYHtyIGFzY2xpc3QgZm9yIDE5OTh9DQojISEhISEhICBDSEFOR0UgQVNDTkFNRSwgQVNDUEFUSCBBTkQgQ1NWIEZJTEUgTkFNRQ0KDQphc2NsYXllciA8LSBzdWJzZXQoYXNjbGF5ZXJhbGwsIGFzY3llYXJzID09IDE5OTgpDQoNCmFzY25hbWUgPC0gbGlzdC5maWxlcygiLi4vZGF0YS9lbnYvYXNjaWkvYXNjaWkxOTk4LyIsIHBhdHRlcm4gPSAiKi5hc2MiLCBmdWxsLm5hbWVzID0gRkFMU0UpICAgICMgdGhpcyBmb2xkZXIgY3VycmVudGx5IGNvbnRhaW5zIG90aGVyIGR1bW15IGZpbGVzLiBpdHMganVzdCBhIHRlc3QgdG8gYXV0b21hdGUgc3RhY2tzDQphc2NwYXRoIDwtIGxpc3QuZmlsZXMoIi4uL2RhdGEvZW52L2FzY2lpL2FzY2lpMTk5OC8iLCBwYXR0ZXJuID0gIiouYXNjIiwgZnVsbC5uYW1lcyA9IFRSVUUpICAgICMgdGhpcyBmb2xkZXIgY3VycmVudGx5IGNvbnRhaW5zIG90aGVyIGR1bW15IGZpbGVzLiBpdHMganVzdCBhIHRlc3QgdG8gYXV0b21hdGUgc3RhY2tzDQoNCnRlbXB2YXIgPC0gInRlbXAubmMiDQpjaGx2YXIgPC0gImNobC5uYyINCm8ydmFyIDwtICJvMi5uYyINCnNhbHZhciA8LSAic2FsaW5pdHkubmMiDQptbHB2YXIgPC0gIm1scC5uYyINCnNzaHZhciA8LSAic3NoLm5jIg0KbmFvc2FtcGxldmFyIDwtICJuYW9zYW1wbGUiDQphbW9zYW1wbGV2YXIgPC0gImFtb3NhbXBsZSINCm5hb3ByZXZ2YXIgPC0gIm5hb3ByZXYiDQphbW9wcmV2dmFyIDwtICJhbW9wcmV2Ig0KbmFvd2ludGVydmFyIDwtICJuYW93aW50ZXIiDQphbW93aW50ZXJ2YXIgPC0gImFtb3dpbnRlciINCnN1cmZhY2V2YXIgPC0gIjAuNTA1NzYiDQoNCmZvciAoaSBpbiAxOm5yb3coYXNjbGF5ZXIpKXsNCiAgICBwcmludChhc2NsYXllciRzdGFja25hbWVbaV0pDQogICAgeWVhciA8LSBhc2NsYXllciRhc2N5ZWFyc1tpXQ0KICAgIG1vbnRoIDwtIGFzY2xheWVyJGFzY21vbnRoc1tpXQ0KICAgIGRlcHRoIDwtIGFzY2xheWVyJGFzY2RlcHRoc1tpXQ0KICAgIA0KICAgIGZvciAoayBpbiAxOmxlbmd0aChhc2NuYW1lKSl7DQogICAgICAgIGFzY3llYXIgPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAxKSkNCiAgICAgICAgYXNjbW9udGggPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAyKSkNCiAgICAgICAgYXNjdmFyIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMykpDQogICAgICAgIGFzY2RlcHRoIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgNCkpDQogICAgICAgIGFzY2RlcHRoIDwtIGdzdWIoIi5hc2MiLCAiIiwgYXNjZGVwdGgpDQogICAgICAgIGFzY2ZpbGUgPC0gYXNjcGF0aFtrXQ0KICAgICAgICANCg0KICAgICAgICBpZiAoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gdGVtcHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciR0ZW1wX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHRlbXB2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciR0ZW1wX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc2FsdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJHNhbGluaXR5X2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNhbHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHNhbGluaXR5X3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gY2hsdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJGNobF9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBjaGx2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRjaGxfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBvMnZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRvMl9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBvMnZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG8yX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbWxwdmFyKXsNCiAgICAgICAgICBhc2NsYXllciRtbHBfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzc2h2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHNzaF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG5hb3NhbXBsZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3NhbXBsZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBhbW9zYW1wbGV2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb19zYW1wbGVbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbmFvcHJldnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3ByZXZbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gYW1vcHJldnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3ByZXZbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjdmFyID09IG5hb3dpbnRlcnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3dpbnRlcltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2N2YXIgPT0gYW1vd2ludGVydmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fd2ludGVyW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfQ0KICAgIH0NCiAgd3JpdGUuY3N2KGFzY2xheWVyLCAiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdDE5OTguY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCn0NCmBgYA0KDQoNCmBgYHtyIGFzY2xpc3QgZm9yIDE5OTl9DQojISEhISEhICBDSEFOR0UgQVNDTEFZRVIgQVNDTkFNRSwgQVNDUEFUSCBBTkQgQ1NWIEZJTEUgTkFNRQ0KDQphc2NsYXllciA8LSBzdWJzZXQoYXNjbGF5ZXJhbGwsIGFzY3llYXJzID09IDE5OTkpDQoNCmFzY25hbWUgPC0gbGlzdC5maWxlcygiLi4vZGF0YS9lbnYvYXNjaWkvYXNjaWkxOTk5LyIsIHBhdHRlcm4gPSAiKi5hc2MiLCBmdWxsLm5hbWVzID0gRkFMU0UpICAgICMgdGhpcyBmb2xkZXIgY3VycmVudGx5IGNvbnRhaW5zIG90aGVyIGR1bW15IGZpbGVzLiBpdHMganVzdCBhIHRlc3QgdG8gYXV0b21hdGUgc3RhY2tzDQphc2NwYXRoIDwtIGxpc3QuZmlsZXMoIi4uL2RhdGEvZW52L2FzY2lpL2FzY2lpMTk5OS8iLCBwYXR0ZXJuID0gIiouYXNjIiwgZnVsbC5uYW1lcyA9IFRSVUUpICAgICMgdGhpcyBmb2xkZXIgY3VycmVudGx5IGNvbnRhaW5zIG90aGVyIGR1bW15IGZpbGVzLiBpdHMganVzdCBhIHRlc3QgdG8gYXV0b21hdGUgc3RhY2tzDQoNCnRlbXB2YXIgPC0gInRlbXAubmMiDQpjaGx2YXIgPC0gImNobC5uYyINCm8ydmFyIDwtICJvMi5uYyINCnNhbHZhciA8LSAic2FsaW5pdHkubmMiDQptbHB2YXIgPC0gIm1scC5uYyINCnNzaHZhciA8LSAic3NoLm5jIg0KbmFvc2FtcGxldmFyIDwtICJuYW9zYW1wbGUiDQphbW9zYW1wbGV2YXIgPC0gImFtb3NhbXBsZSINCm5hb3ByZXZ2YXIgPC0gIm5hb3ByZXYiDQphbW9wcmV2dmFyIDwtICJhbW9wcmV2Ig0KbmFvd2ludGVydmFyIDwtICJuYW93aW50ZXIiDQphbW93aW50ZXJ2YXIgPC0gImFtb3dpbnRlciINCnN1cmZhY2V2YXIgPC0gIjAuNTA1NzYiDQoNCmZvciAoaSBpbiAxOm5yb3coYXNjbGF5ZXIpKXsNCiAgICBwcmludChhc2NsYXllciRzdGFja25hbWVbaV0pDQogICAgeWVhciA8LSBhc2NsYXllciRhc2N5ZWFyc1tpXQ0KICAgIG1vbnRoIDwtIGFzY2xheWVyJGFzY21vbnRoc1tpXQ0KICAgIGRlcHRoIDwtIGFzY2xheWVyJGFzY2RlcHRoc1tpXQ0KICAgIA0KICAgIGZvciAoayBpbiAxOmxlbmd0aChhc2NuYW1lKSl7DQogICAgICAgIGFzY3llYXIgPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAxKSkNCiAgICAgICAgYXNjbW9udGggPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAyKSkNCiAgICAgICAgYXNjdmFyIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMykpDQogICAgICAgIGFzY2RlcHRoIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgNCkpDQogICAgICAgIGFzY2RlcHRoIDwtIGdzdWIoIi5hc2MiLCAiIiwgYXNjZGVwdGgpDQogICAgICAgIGFzY2ZpbGUgPC0gYXNjcGF0aFtrXQ0KICAgICAgICANCg0KICAgICAgICBpZiAoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gdGVtcHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciR0ZW1wX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHRlbXB2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciR0ZW1wX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc2FsdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJHNhbGluaXR5X2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNhbHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHNhbGluaXR5X3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gY2hsdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJGNobF9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBjaGx2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRjaGxfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBvMnZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRvMl9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBvMnZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG8yX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbWxwdmFyKXsNCiAgICAgICAgICBhc2NsYXllciRtbHBfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzc2h2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHNzaF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG5hb3NhbXBsZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3NhbXBsZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBhbW9zYW1wbGV2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb19zYW1wbGVbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbmFvcHJldnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3ByZXZbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gYW1vcHJldnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3ByZXZbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjdmFyID09IG5hb3dpbnRlcnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3dpbnRlcltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2N2YXIgPT0gYW1vd2ludGVydmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fd2ludGVyW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfQ0KICAgIH0NCiAgd3JpdGUuY3N2KGFzY2xheWVyLCAiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdDE5OTkuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCn0NCmBgYA0KDQpgYGB7ciBhc2NsaXN0IGZvciAyMDAwfQ0KIyEhISEhISAgQ0hBTkdFIEFTQ05BTUUsIEFTQ1BBVEggQU5EIENTViBGSUxFIE5BTUUNCg0KYXNjbGF5ZXIgPC0gc3Vic2V0KGFzY2xheWVyYWxsLCBhc2N5ZWFycyA9PSAyMDAwKQ0KDQphc2NuYW1lIDwtIGxpc3QuZmlsZXMoIi4uL2RhdGEvZW52L2FzY2lpL2FzY2lpMjAwMC8iLCBwYXR0ZXJuID0gIiouYXNjIiwgZnVsbC5uYW1lcyA9IEZBTFNFKSAgICAjIHRoaXMgZm9sZGVyIGN1cnJlbnRseSBjb250YWlucyBvdGhlciBkdW1teSBmaWxlcy4gaXRzIGp1c3QgYSB0ZXN0IHRvIGF1dG9tYXRlIHN0YWNrcw0KYXNjcGF0aCA8LSBsaXN0LmZpbGVzKCIuLi9kYXRhL2Vudi9hc2NpaS9hc2NpaTIwMDAvIiwgcGF0dGVybiA9ICIqLmFzYyIsIGZ1bGwubmFtZXMgPSBUUlVFKSAgICAjIHRoaXMgZm9sZGVyIGN1cnJlbnRseSBjb250YWlucyBvdGhlciBkdW1teSBmaWxlcy4gaXRzIGp1c3QgYSB0ZXN0IHRvIGF1dG9tYXRlIHN0YWNrcw0KDQp0ZW1wdmFyIDwtICJ0ZW1wLm5jIg0KY2hsdmFyIDwtICJjaGwubmMiDQpvMnZhciA8LSAibzIubmMiDQpzYWx2YXIgPC0gInNhbGluaXR5Lm5jIg0KbWxwdmFyIDwtICJtbHAubmMiDQpzc2h2YXIgPC0gInNzaC5uYyINCm5hb3NhbXBsZXZhciA8LSAibmFvc2FtcGxlIg0KYW1vc2FtcGxldmFyIDwtICJhbW9zYW1wbGUiDQpuYW9wcmV2dmFyIDwtICJuYW9wcmV2Ig0KYW1vcHJldnZhciA8LSAiYW1vcHJldiINCm5hb3dpbnRlcnZhciA8LSAibmFvd2ludGVyIg0KYW1vd2ludGVydmFyIDwtICJhbW93aW50ZXIiDQpzdXJmYWNldmFyIDwtICIwLjUwNTc2Ig0KDQpmb3IgKGkgaW4gMTpucm93KGFzY2xheWVyKSl7DQogICAgcHJpbnQoYXNjbGF5ZXIkc3RhY2tuYW1lW2ldKQ0KICAgIHllYXIgPC0gYXNjbGF5ZXIkYXNjeWVhcnNbaV0NCiAgICBtb250aCA8LSBhc2NsYXllciRhc2Ntb250aHNbaV0NCiAgICBkZXB0aCA8LSBhc2NsYXllciRhc2NkZXB0aHNbaV0NCiAgICANCiAgICBmb3IgKGsgaW4gMTpsZW5ndGgoYXNjbmFtZSkpew0KICAgICAgICBhc2N5ZWFyIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMSkpDQogICAgICAgIGFzY21vbnRoIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMikpDQogICAgICAgIGFzY3ZhciA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDMpKQ0KICAgICAgICBhc2NkZXB0aCA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDQpKQ0KICAgICAgICBhc2NkZXB0aCA8LSBnc3ViKCIuYXNjIiwgIiIsIGFzY2RlcHRoKQ0KICAgICAgICBhc2NmaWxlIDwtIGFzY3BhdGhba10NCiAgICAgICAgDQoNCiAgICAgICAgaWYgKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHRlbXB2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkdGVtcF9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSB0ZW1wdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkdGVtcF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNhbHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRzYWxpbml0eV9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzYWx2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRzYWxpbml0eV9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGNobHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRjaGxfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gY2hsdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkY2hsX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbzJ2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkbzJfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbzJ2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRvMl9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG1scHZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbWxwX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc3NodmFyKXsNCiAgICAgICAgICBhc2NsYXllciRzc2hfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBuYW9zYW1wbGV2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb19zYW1wbGVbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gYW1vc2FtcGxldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fc2FtcGxlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG5hb3ByZXZ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb19wcmV2W2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGFtb3ByZXZ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb19wcmV2W2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY3ZhciA9PSBuYW93aW50ZXJ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb193aW50ZXJbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjdmFyID09IGFtb3dpbnRlcnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3dpbnRlcltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0NCiAgICB9DQogIHdyaXRlLmNzdihhc2NsYXllciwgIi4uL2RhdGEvZW52L2FzY19sYXllcmxpc3QyMDAwLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp9DQpgYGANCg0KYGBge3IgYXNjbGlzdCBmb3IgMjAwMX0NCiMhISEhISEgIENIQU5HRSBBU0NOQU1FLCBBU0NQQVRIIEFORCBDU1YgRklMRSBOQU1FDQoNCmFzY2xheWVyIDwtIHN1YnNldChhc2NsYXllcmFsbCwgYXNjeWVhcnMgPT0gMjAwMSkNCg0KYXNjbmFtZSA8LSBsaXN0LmZpbGVzKCIuLi9kYXRhL2Vudi9hc2NpaS9hc2NpaTIwMDEvIiwgcGF0dGVybiA9ICIqLmFzYyIsIGZ1bGwubmFtZXMgPSBGQUxTRSkgICAgIyB0aGlzIGZvbGRlciBjdXJyZW50bHkgY29udGFpbnMgb3RoZXIgZHVtbXkgZmlsZXMuIGl0cyBqdXN0IGEgdGVzdCB0byBhdXRvbWF0ZSBzdGFja3MNCmFzY3BhdGggPC0gbGlzdC5maWxlcygiLi4vZGF0YS9lbnYvYXNjaWkvYXNjaWkyMDAxLyIsIHBhdHRlcm4gPSAiKi5hc2MiLCBmdWxsLm5hbWVzID0gVFJVRSkgICAgIyB0aGlzIGZvbGRlciBjdXJyZW50bHkgY29udGFpbnMgb3RoZXIgZHVtbXkgZmlsZXMuIGl0cyBqdXN0IGEgdGVzdCB0byBhdXRvbWF0ZSBzdGFja3MNCg0KdGVtcHZhciA8LSAidGVtcC5uYyINCmNobHZhciA8LSAiY2hsLm5jIg0KbzJ2YXIgPC0gIm8yLm5jIg0Kc2FsdmFyIDwtICJzYWxpbml0eS5uYyINCm1scHZhciA8LSAibWxwLm5jIg0Kc3NodmFyIDwtICJzc2gubmMiDQpuYW9zYW1wbGV2YXIgPC0gIm5hb3NhbXBsZSINCmFtb3NhbXBsZXZhciA8LSAiYW1vc2FtcGxlIg0KbmFvcHJldnZhciA8LSAibmFvcHJldiINCmFtb3ByZXZ2YXIgPC0gImFtb3ByZXYiDQpuYW93aW50ZXJ2YXIgPC0gIm5hb3dpbnRlciINCmFtb3dpbnRlcnZhciA8LSAiYW1vd2ludGVyIg0Kc3VyZmFjZXZhciA8LSAiMC41MDU3NiINCg0KZm9yIChpIGluIDE6bnJvdyhhc2NsYXllcikpew0KICAgIHByaW50KGFzY2xheWVyJHN0YWNrbmFtZVtpXSkNCiAgICB5ZWFyIDwtIGFzY2xheWVyJGFzY3llYXJzW2ldDQogICAgbW9udGggPC0gYXNjbGF5ZXIkYXNjbW9udGhzW2ldDQogICAgZGVwdGggPC0gYXNjbGF5ZXIkYXNjZGVwdGhzW2ldDQogICAgDQogICAgZm9yIChrIGluIDE6bGVuZ3RoKGFzY25hbWUpKXsNCiAgICAgICAgYXNjeWVhciA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDEpKQ0KICAgICAgICBhc2Ntb250aCA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDIpKQ0KICAgICAgICBhc2N2YXIgPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAzKSkNCiAgICAgICAgYXNjZGVwdGggPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCA0KSkNCiAgICAgICAgYXNjZGVwdGggPC0gZ3N1YigiLmFzYyIsICIiLCBhc2NkZXB0aCkNCiAgICAgICAgYXNjZmlsZSA8LSBhc2NwYXRoW2tdDQogICAgICAgIA0KDQogICAgICAgIGlmIChhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSB0ZW1wdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJHRlbXBfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gdGVtcHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHRlbXBfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzYWx2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkc2FsaW5pdHlfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc2FsdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkc2FsaW5pdHlfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBjaGx2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkY2hsX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGNobHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGNobF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG8ydmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJG8yX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG8ydmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbzJfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBtbHB2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG1scF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNzaHZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkc3NoX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbmFvc2FtcGxldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRuYW9fc2FtcGxlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGFtb3NhbXBsZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3NhbXBsZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBuYW9wcmV2dmFyKXsNCiAgICAgICAgICBhc2NsYXllciRuYW9fcHJldltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBhbW9wcmV2dmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fcHJldltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2N2YXIgPT0gbmFvd2ludGVydmFyKXsNCiAgICAgICAgICBhc2NsYXllciRuYW9fd2ludGVyW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY3ZhciA9PSBhbW93aW50ZXJ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb193aW50ZXJbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9DQogICAgfQ0KICB3cml0ZS5jc3YoYXNjbGF5ZXIsICIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0MjAwMS5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KfQ0KYGBgDQoNCmBgYHtyIGFzY2xpc3QgZm9yIDIwMDJ9DQojISEhISEhICBDSEFOR0UgQVNDTkFNRSwgQVNDUEFUSCBBTkQgQ1NWIEZJTEUgTkFNRQ0KDQphc2NsYXllciA8LSBzdWJzZXQoYXNjbGF5ZXJhbGwsIGFzY3llYXJzID09IDIwMDIpDQoNCmFzY25hbWUgPC0gbGlzdC5maWxlcygiLi4vZGF0YS9lbnYvYXNjaWkvYXNjaWkyMDAyLyIsIHBhdHRlcm4gPSAiKi5hc2MiLCBmdWxsLm5hbWVzID0gRkFMU0UpICAgICMgdGhpcyBmb2xkZXIgY3VycmVudGx5IGNvbnRhaW5zIG90aGVyIGR1bW15IGZpbGVzLiBpdHMganVzdCBhIHRlc3QgdG8gYXV0b21hdGUgc3RhY2tzDQphc2NwYXRoIDwtIGxpc3QuZmlsZXMoIi4uL2RhdGEvZW52L2FzY2lpL2FzY2lpMjAwMi8iLCBwYXR0ZXJuID0gIiouYXNjIiwgZnVsbC5uYW1lcyA9IFRSVUUpICAgICMgdGhpcyBmb2xkZXIgY3VycmVudGx5IGNvbnRhaW5zIG90aGVyIGR1bW15IGZpbGVzLiBpdHMganVzdCBhIHRlc3QgdG8gYXV0b21hdGUgc3RhY2tzDQoNCnRlbXB2YXIgPC0gInRlbXAubmMiDQpjaGx2YXIgPC0gImNobC5uYyINCm8ydmFyIDwtICJvMi5uYyINCnNhbHZhciA8LSAic2FsaW5pdHkubmMiDQptbHB2YXIgPC0gIm1scC5uYyINCnNzaHZhciA8LSAic3NoLm5jIg0KbmFvc2FtcGxldmFyIDwtICJuYW9zYW1wbGUiDQphbW9zYW1wbGV2YXIgPC0gImFtb3NhbXBsZSINCm5hb3ByZXZ2YXIgPC0gIm5hb3ByZXYiDQphbW9wcmV2dmFyIDwtICJhbW9wcmV2Ig0KbmFvd2ludGVydmFyIDwtICJuYW93aW50ZXIiDQphbW93aW50ZXJ2YXIgPC0gImFtb3dpbnRlciINCnN1cmZhY2V2YXIgPC0gIjAuNTA1NzYiDQoNCmZvciAoaSBpbiAxOm5yb3coYXNjbGF5ZXIpKXsNCiAgICBwcmludChhc2NsYXllciRzdGFja25hbWVbaV0pDQogICAgeWVhciA8LSBhc2NsYXllciRhc2N5ZWFyc1tpXQ0KICAgIG1vbnRoIDwtIGFzY2xheWVyJGFzY21vbnRoc1tpXQ0KICAgIGRlcHRoIDwtIGFzY2xheWVyJGFzY2RlcHRoc1tpXQ0KICAgIA0KICAgIGZvciAoayBpbiAxOmxlbmd0aChhc2NuYW1lKSl7DQogICAgICAgIGFzY3llYXIgPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAxKSkNCiAgICAgICAgYXNjbW9udGggPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAyKSkNCiAgICAgICAgYXNjdmFyIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMykpDQogICAgICAgIGFzY2RlcHRoIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgNCkpDQogICAgICAgIGFzY2RlcHRoIDwtIGdzdWIoIi5hc2MiLCAiIiwgYXNjZGVwdGgpDQogICAgICAgIGFzY2ZpbGUgPC0gYXNjcGF0aFtrXQ0KICAgICAgICANCg0KICAgICAgICBpZiAoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gdGVtcHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciR0ZW1wX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHRlbXB2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciR0ZW1wX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc2FsdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJHNhbGluaXR5X2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNhbHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHNhbGluaXR5X3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gY2hsdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJGNobF9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBjaGx2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRjaGxfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBvMnZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRvMl9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBvMnZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG8yX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbWxwdmFyKXsNCiAgICAgICAgICBhc2NsYXllciRtbHBfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzc2h2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHNzaF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG5hb3NhbXBsZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3NhbXBsZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBhbW9zYW1wbGV2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb19zYW1wbGVbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbmFvcHJldnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3ByZXZbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gYW1vcHJldnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3ByZXZbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjdmFyID09IG5hb3dpbnRlcnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3dpbnRlcltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2N2YXIgPT0gYW1vd2ludGVydmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fd2ludGVyW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfQ0KICAgIH0NCiAgd3JpdGUuY3N2KGFzY2xheWVyLCAiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdDIwMDIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCn0NCmBgYA0KDQpgYGB7ciBhc2NsaXN0IGZvciAyMDAzfQ0KIyEhISEhISAgQ0hBTkdFIEFTQ05BTUUsIEFTQ1BBVEggQU5EIENTViBGSUxFIE5BTUUNCg0KYXNjbGF5ZXIgPC0gc3Vic2V0KGFzY2xheWVyYWxsLCBhc2N5ZWFycyA9PSAyMDAzKQ0KDQphc2NuYW1lIDwtIGxpc3QuZmlsZXMoIi4uL2RhdGEvZW52L2FzY2lpL2FzY2lpMjAwMy8iLCBwYXR0ZXJuID0gIiouYXNjIiwgZnVsbC5uYW1lcyA9IEZBTFNFKSAgICAjIHRoaXMgZm9sZGVyIGN1cnJlbnRseSBjb250YWlucyBvdGhlciBkdW1teSBmaWxlcy4gaXRzIGp1c3QgYSB0ZXN0IHRvIGF1dG9tYXRlIHN0YWNrcw0KYXNjcGF0aCA8LSBsaXN0LmZpbGVzKCIuLi9kYXRhL2Vudi9hc2NpaS9hc2NpaTIwMDMvIiwgcGF0dGVybiA9ICIqLmFzYyIsIGZ1bGwubmFtZXMgPSBUUlVFKSAgICAjIHRoaXMgZm9sZGVyIGN1cnJlbnRseSBjb250YWlucyBvdGhlciBkdW1teSBmaWxlcy4gaXRzIGp1c3QgYSB0ZXN0IHRvIGF1dG9tYXRlIHN0YWNrcw0KDQp0ZW1wdmFyIDwtICJ0ZW1wLm5jIg0KY2hsdmFyIDwtICJjaGwubmMiDQpvMnZhciA8LSAibzIubmMiDQpzYWx2YXIgPC0gInNhbGluaXR5Lm5jIg0KbWxwdmFyIDwtICJtbHAubmMiDQpzc2h2YXIgPC0gInNzaC5uYyINCm5hb3NhbXBsZXZhciA8LSAibmFvc2FtcGxlIg0KYW1vc2FtcGxldmFyIDwtICJhbW9zYW1wbGUiDQpuYW9wcmV2dmFyIDwtICJuYW9wcmV2Ig0KYW1vcHJldnZhciA8LSAiYW1vcHJldiINCm5hb3dpbnRlcnZhciA8LSAibmFvd2ludGVyIg0KYW1vd2ludGVydmFyIDwtICJhbW93aW50ZXIiDQpzdXJmYWNldmFyIDwtICIwLjUwNTc2Ig0KDQpmb3IgKGkgaW4gMTpucm93KGFzY2xheWVyKSl7DQogICAgcHJpbnQoYXNjbGF5ZXIkc3RhY2tuYW1lW2ldKQ0KICAgIHllYXIgPC0gYXNjbGF5ZXIkYXNjeWVhcnNbaV0NCiAgICBtb250aCA8LSBhc2NsYXllciRhc2Ntb250aHNbaV0NCiAgICBkZXB0aCA8LSBhc2NsYXllciRhc2NkZXB0aHNbaV0NCiAgICANCiAgICBmb3IgKGsgaW4gMTpsZW5ndGgoYXNjbmFtZSkpew0KICAgICAgICBhc2N5ZWFyIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMSkpDQogICAgICAgIGFzY21vbnRoIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMikpDQogICAgICAgIGFzY3ZhciA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDMpKQ0KICAgICAgICBhc2NkZXB0aCA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDQpKQ0KICAgICAgICBhc2NkZXB0aCA8LSBnc3ViKCIuYXNjIiwgIiIsIGFzY2RlcHRoKQ0KICAgICAgICBhc2NmaWxlIDwtIGFzY3BhdGhba10NCiAgICAgICAgDQoNCiAgICAgICAgaWYgKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHRlbXB2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkdGVtcF9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSB0ZW1wdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkdGVtcF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNhbHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRzYWxpbml0eV9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzYWx2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRzYWxpbml0eV9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGNobHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRjaGxfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gY2hsdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkY2hsX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbzJ2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkbzJfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbzJ2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRvMl9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG1scHZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbWxwX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc3NodmFyKXsNCiAgICAgICAgICBhc2NsYXllciRzc2hfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBuYW9zYW1wbGV2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb19zYW1wbGVbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gYW1vc2FtcGxldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fc2FtcGxlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG5hb3ByZXZ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb19wcmV2W2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGFtb3ByZXZ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb19wcmV2W2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY3ZhciA9PSBuYW93aW50ZXJ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb193aW50ZXJbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjdmFyID09IGFtb3dpbnRlcnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3dpbnRlcltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0NCiAgICB9DQogIHdyaXRlLmNzdihhc2NsYXllciwgIi4uL2RhdGEvZW52L2FzY19sYXllcmxpc3QyMDAzLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp9DQpgYGANCg0KYGBge3IgYXNjbGlzdCBmb3IgMjAwNH0NCiMhISEhISEgIENIQU5HRSBBU0NOQU1FLCBBU0NQQVRIIEFORCBDU1YgRklMRSBOQU1FDQoNCmFzY2xheWVyIDwtIHN1YnNldChhc2NsYXllcmFsbCwgYXNjeWVhcnMgPT0gMjAwNCkNCg0KYXNjbmFtZSA8LSBsaXN0LmZpbGVzKCIuLi9kYXRhL2Vudi9hc2NpaS9hc2NpaTIwMDQvIiwgcGF0dGVybiA9ICIqLmFzYyIsIGZ1bGwubmFtZXMgPSBGQUxTRSkgICAgIyB0aGlzIGZvbGRlciBjdXJyZW50bHkgY29udGFpbnMgb3RoZXIgZHVtbXkgZmlsZXMuIGl0cyBqdXN0IGEgdGVzdCB0byBhdXRvbWF0ZSBzdGFja3MNCmFzY3BhdGggPC0gbGlzdC5maWxlcygiLi4vZGF0YS9lbnYvYXNjaWkvYXNjaWkyMDA0LyIsIHBhdHRlcm4gPSAiKi5hc2MiLCBmdWxsLm5hbWVzID0gVFJVRSkgICAgIyB0aGlzIGZvbGRlciBjdXJyZW50bHkgY29udGFpbnMgb3RoZXIgZHVtbXkgZmlsZXMuIGl0cyBqdXN0IGEgdGVzdCB0byBhdXRvbWF0ZSBzdGFja3MNCg0KdGVtcHZhciA8LSAidGVtcC5uYyINCmNobHZhciA8LSAiY2hsLm5jIg0KbzJ2YXIgPC0gIm8yLm5jIg0Kc2FsdmFyIDwtICJzYWxpbml0eS5uYyINCm1scHZhciA8LSAibWxwLm5jIg0Kc3NodmFyIDwtICJzc2gubmMiDQpuYW9zYW1wbGV2YXIgPC0gIm5hb3NhbXBsZSINCmFtb3NhbXBsZXZhciA8LSAiYW1vc2FtcGxlIg0KbmFvcHJldnZhciA8LSAibmFvcHJldiINCmFtb3ByZXZ2YXIgPC0gImFtb3ByZXYiDQpuYW93aW50ZXJ2YXIgPC0gIm5hb3dpbnRlciINCmFtb3dpbnRlcnZhciA8LSAiYW1vd2ludGVyIg0Kc3VyZmFjZXZhciA8LSAiMC41MDU3NiINCg0KZm9yIChpIGluIDE6bnJvdyhhc2NsYXllcikpew0KICAgIHByaW50KGFzY2xheWVyJHN0YWNrbmFtZVtpXSkNCiAgICB5ZWFyIDwtIGFzY2xheWVyJGFzY3llYXJzW2ldDQogICAgbW9udGggPC0gYXNjbGF5ZXIkYXNjbW9udGhzW2ldDQogICAgZGVwdGggPC0gYXNjbGF5ZXIkYXNjZGVwdGhzW2ldDQogICAgDQogICAgZm9yIChrIGluIDE6bGVuZ3RoKGFzY25hbWUpKXsNCiAgICAgICAgYXNjeWVhciA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDEpKQ0KICAgICAgICBhc2Ntb250aCA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDIpKQ0KICAgICAgICBhc2N2YXIgPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAzKSkNCiAgICAgICAgYXNjZGVwdGggPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCA0KSkNCiAgICAgICAgYXNjZGVwdGggPC0gZ3N1YigiLmFzYyIsICIiLCBhc2NkZXB0aCkNCiAgICAgICAgYXNjZmlsZSA8LSBhc2NwYXRoW2tdDQogICAgICAgIA0KDQogICAgICAgIGlmIChhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSB0ZW1wdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJHRlbXBfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gdGVtcHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHRlbXBfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzYWx2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkc2FsaW5pdHlfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc2FsdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkc2FsaW5pdHlfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBjaGx2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkY2hsX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGNobHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGNobF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG8ydmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJG8yX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG8ydmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbzJfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBtbHB2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG1scF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNzaHZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkc3NoX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbmFvc2FtcGxldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRuYW9fc2FtcGxlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGFtb3NhbXBsZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3NhbXBsZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBuYW9wcmV2dmFyKXsNCiAgICAgICAgICBhc2NsYXllciRuYW9fcHJldltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBhbW9wcmV2dmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fcHJldltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2N2YXIgPT0gbmFvd2ludGVydmFyKXsNCiAgICAgICAgICBhc2NsYXllciRuYW9fd2ludGVyW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY3ZhciA9PSBhbW93aW50ZXJ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb193aW50ZXJbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9DQogICAgfQ0KICB3cml0ZS5jc3YoYXNjbGF5ZXIsICIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0MjAwNC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KfQ0KYGBgDQoNCmBgYHtyIGFzY2xpc3QgZm9yIDIwMDV9DQojISEhISEhICBDSEFOR0UgQVNDTkFNRSwgQVNDUEFUSCBBTkQgQ1NWIEZJTEUgTkFNRQ0KDQphc2NsYXllciA8LSBzdWJzZXQoYXNjbGF5ZXJhbGwsIGFzY3llYXJzID09IDIwMDUpDQoNCmFzY25hbWUgPC0gbGlzdC5maWxlcygiLi4vZGF0YS9lbnYvYXNjaWkvYXNjaWkyMDA1LyIsIHBhdHRlcm4gPSAiKi5hc2MiLCBmdWxsLm5hbWVzID0gRkFMU0UpICAgICMgdGhpcyBmb2xkZXIgY3VycmVudGx5IGNvbnRhaW5zIG90aGVyIGR1bW15IGZpbGVzLiBpdHMganVzdCBhIHRlc3QgdG8gYXV0b21hdGUgc3RhY2tzDQphc2NwYXRoIDwtIGxpc3QuZmlsZXMoIi4uL2RhdGEvZW52L2FzY2lpL2FzY2lpMjAwNS8iLCBwYXR0ZXJuID0gIiouYXNjIiwgZnVsbC5uYW1lcyA9IFRSVUUpICAgICMgdGhpcyBmb2xkZXIgY3VycmVudGx5IGNvbnRhaW5zIG90aGVyIGR1bW15IGZpbGVzLiBpdHMganVzdCBhIHRlc3QgdG8gYXV0b21hdGUgc3RhY2tzDQoNCnRlbXB2YXIgPC0gInRlbXAubmMiDQpjaGx2YXIgPC0gImNobC5uYyINCm8ydmFyIDwtICJvMi5uYyINCnNhbHZhciA8LSAic2FsaW5pdHkubmMiDQptbHB2YXIgPC0gIm1scC5uYyINCnNzaHZhciA8LSAic3NoLm5jIg0KbmFvc2FtcGxldmFyIDwtICJuYW9zYW1wbGUiDQphbW9zYW1wbGV2YXIgPC0gImFtb3NhbXBsZSINCm5hb3ByZXZ2YXIgPC0gIm5hb3ByZXYiDQphbW9wcmV2dmFyIDwtICJhbW9wcmV2Ig0KbmFvd2ludGVydmFyIDwtICJuYW93aW50ZXIiDQphbW93aW50ZXJ2YXIgPC0gImFtb3dpbnRlciINCnN1cmZhY2V2YXIgPC0gIjAuNTA1NzYiDQoNCmZvciAoaSBpbiAxOm5yb3coYXNjbGF5ZXIpKXsNCiAgICBwcmludChhc2NsYXllciRzdGFja25hbWVbaV0pDQogICAgeWVhciA8LSBhc2NsYXllciRhc2N5ZWFyc1tpXQ0KICAgIG1vbnRoIDwtIGFzY2xheWVyJGFzY21vbnRoc1tpXQ0KICAgIGRlcHRoIDwtIGFzY2xheWVyJGFzY2RlcHRoc1tpXQ0KICAgIA0KICAgIGZvciAoayBpbiAxOmxlbmd0aChhc2NuYW1lKSl7DQogICAgICAgIGFzY3llYXIgPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAxKSkNCiAgICAgICAgYXNjbW9udGggPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAyKSkNCiAgICAgICAgYXNjdmFyIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMykpDQogICAgICAgIGFzY2RlcHRoIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgNCkpDQogICAgICAgIGFzY2RlcHRoIDwtIGdzdWIoIi5hc2MiLCAiIiwgYXNjZGVwdGgpDQogICAgICAgIGFzY2ZpbGUgPC0gYXNjcGF0aFtrXQ0KICAgICAgICANCg0KICAgICAgICBpZiAoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gdGVtcHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciR0ZW1wX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHRlbXB2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciR0ZW1wX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc2FsdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJHNhbGluaXR5X2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNhbHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHNhbGluaXR5X3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gY2hsdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJGNobF9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBjaGx2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRjaGxfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBvMnZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRvMl9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBvMnZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG8yX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbWxwdmFyKXsNCiAgICAgICAgICBhc2NsYXllciRtbHBfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzc2h2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHNzaF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG5hb3NhbXBsZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3NhbXBsZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBhbW9zYW1wbGV2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb19zYW1wbGVbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbmFvcHJldnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3ByZXZbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gYW1vcHJldnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3ByZXZbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjdmFyID09IG5hb3dpbnRlcnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3dpbnRlcltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2N2YXIgPT0gYW1vd2ludGVydmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fd2ludGVyW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfQ0KICAgIH0NCiAgd3JpdGUuY3N2KGFzY2xheWVyLCAiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdDIwMDUuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCn0NCmBgYA0KDQpgYGB7ciBhc2NsaXN0IGZvciAyMDA2fQ0KIyEhISEhISAgQ0hBTkdFIEFTQ05BTUUsIEFTQ1BBVEggQU5EIENTViBGSUxFIE5BTUUNCg0KYXNjbGF5ZXIgPC0gc3Vic2V0KGFzY2xheWVyYWxsLCBhc2N5ZWFycyA9PSAyMDA2KQ0KDQphc2NuYW1lIDwtIGxpc3QuZmlsZXMoIi4uL2RhdGEvZW52L2FzY2lpL2FzY2lpMjAwNi8iLCBwYXR0ZXJuID0gIiouYXNjIiwgZnVsbC5uYW1lcyA9IEZBTFNFKSAgICAjIHRoaXMgZm9sZGVyIGN1cnJlbnRseSBjb250YWlucyBvdGhlciBkdW1teSBmaWxlcy4gaXRzIGp1c3QgYSB0ZXN0IHRvIGF1dG9tYXRlIHN0YWNrcw0KYXNjcGF0aCA8LSBsaXN0LmZpbGVzKCIuLi9kYXRhL2Vudi9hc2NpaS9hc2NpaTIwMDYvIiwgcGF0dGVybiA9ICIqLmFzYyIsIGZ1bGwubmFtZXMgPSBUUlVFKSAgICAjIHRoaXMgZm9sZGVyIGN1cnJlbnRseSBjb250YWlucyBvdGhlciBkdW1teSBmaWxlcy4gaXRzIGp1c3QgYSB0ZXN0IHRvIGF1dG9tYXRlIHN0YWNrcw0KDQp0ZW1wdmFyIDwtICJ0ZW1wLm5jIg0KY2hsdmFyIDwtICJjaGwubmMiDQpvMnZhciA8LSAibzIubmMiDQpzYWx2YXIgPC0gInNhbGluaXR5Lm5jIg0KbWxwdmFyIDwtICJtbHAubmMiDQpzc2h2YXIgPC0gInNzaC5uYyINCm5hb3NhbXBsZXZhciA8LSAibmFvc2FtcGxlIg0KYW1vc2FtcGxldmFyIDwtICJhbW9zYW1wbGUiDQpuYW9wcmV2dmFyIDwtICJuYW9wcmV2Ig0KYW1vcHJldnZhciA8LSAiYW1vcHJldiINCm5hb3dpbnRlcnZhciA8LSAibmFvd2ludGVyIg0KYW1vd2ludGVydmFyIDwtICJhbW93aW50ZXIiDQpzdXJmYWNldmFyIDwtICIwLjUwNTc2Ig0KDQpmb3IgKGkgaW4gMTpucm93KGFzY2xheWVyKSl7DQogICAgcHJpbnQoYXNjbGF5ZXIkc3RhY2tuYW1lW2ldKQ0KICAgIHllYXIgPC0gYXNjbGF5ZXIkYXNjeWVhcnNbaV0NCiAgICBtb250aCA8LSBhc2NsYXllciRhc2Ntb250aHNbaV0NCiAgICBkZXB0aCA8LSBhc2NsYXllciRhc2NkZXB0aHNbaV0NCiAgICANCiAgICBmb3IgKGsgaW4gMTpsZW5ndGgoYXNjbmFtZSkpew0KICAgICAgICBhc2N5ZWFyIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMSkpDQogICAgICAgIGFzY21vbnRoIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMikpDQogICAgICAgIGFzY3ZhciA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDMpKQ0KICAgICAgICBhc2NkZXB0aCA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDQpKQ0KICAgICAgICBhc2NkZXB0aCA8LSBnc3ViKCIuYXNjIiwgIiIsIGFzY2RlcHRoKQ0KICAgICAgICBhc2NmaWxlIDwtIGFzY3BhdGhba10NCiAgICAgICAgDQoNCiAgICAgICAgaWYgKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHRlbXB2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkdGVtcF9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSB0ZW1wdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkdGVtcF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNhbHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRzYWxpbml0eV9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzYWx2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRzYWxpbml0eV9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGNobHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRjaGxfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gY2hsdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkY2hsX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbzJ2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkbzJfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbzJ2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRvMl9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG1scHZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbWxwX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc3NodmFyKXsNCiAgICAgICAgICBhc2NsYXllciRzc2hfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBuYW9zYW1wbGV2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb19zYW1wbGVbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gYW1vc2FtcGxldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fc2FtcGxlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG5hb3ByZXZ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb19wcmV2W2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGFtb3ByZXZ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb19wcmV2W2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY3ZhciA9PSBuYW93aW50ZXJ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb193aW50ZXJbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjdmFyID09IGFtb3dpbnRlcnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3dpbnRlcltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0NCiAgICB9DQogIHdyaXRlLmNzdihhc2NsYXllciwgIi4uL2RhdGEvZW52L2FzY19sYXllcmxpc3QyMDA2LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp9DQpgYGANCg0KYGBge3IgYXNjbGlzdCBmb3IgMjAwN30NCiMhISEhISEgIENIQU5HRSBBU0NOQU1FLCBBU0NQQVRIIEFORCBDU1YgRklMRSBOQU1FDQoNCmFzY2xheWVyIDwtIHN1YnNldChhc2NsYXllcmFsbCwgYXNjeWVhcnMgPT0gMjAwNykNCg0KYXNjbmFtZSA8LSBsaXN0LmZpbGVzKCIuLi9kYXRhL2Vudi9hc2NpaS9hc2NpaTIwMDcvIiwgcGF0dGVybiA9ICIqLmFzYyIsIGZ1bGwubmFtZXMgPSBGQUxTRSkgICAgIyB0aGlzIGZvbGRlciBjdXJyZW50bHkgY29udGFpbnMgb3RoZXIgZHVtbXkgZmlsZXMuIGl0cyBqdXN0IGEgdGVzdCB0byBhdXRvbWF0ZSBzdGFja3MNCmFzY3BhdGggPC0gbGlzdC5maWxlcygiLi4vZGF0YS9lbnYvYXNjaWkvYXNjaWkyMDA3LyIsIHBhdHRlcm4gPSAiKi5hc2MiLCBmdWxsLm5hbWVzID0gVFJVRSkgICAgIyB0aGlzIGZvbGRlciBjdXJyZW50bHkgY29udGFpbnMgb3RoZXIgZHVtbXkgZmlsZXMuIGl0cyBqdXN0IGEgdGVzdCB0byBhdXRvbWF0ZSBzdGFja3MNCg0KdGVtcHZhciA8LSAidGVtcC5uYyINCmNobHZhciA8LSAiY2hsLm5jIg0KbzJ2YXIgPC0gIm8yLm5jIg0Kc2FsdmFyIDwtICJzYWxpbml0eS5uYyINCm1scHZhciA8LSAibWxwLm5jIg0Kc3NodmFyIDwtICJzc2gubmMiDQpuYW9zYW1wbGV2YXIgPC0gIm5hb3NhbXBsZSINCmFtb3NhbXBsZXZhciA8LSAiYW1vc2FtcGxlIg0KbmFvcHJldnZhciA8LSAibmFvcHJldiINCmFtb3ByZXZ2YXIgPC0gImFtb3ByZXYiDQpuYW93aW50ZXJ2YXIgPC0gIm5hb3dpbnRlciINCmFtb3dpbnRlcnZhciA8LSAiYW1vd2ludGVyIg0Kc3VyZmFjZXZhciA8LSAiMC41MDU3NiINCg0KZm9yIChpIGluIDE6bnJvdyhhc2NsYXllcikpew0KICAgIHByaW50KGFzY2xheWVyJHN0YWNrbmFtZVtpXSkNCiAgICB5ZWFyIDwtIGFzY2xheWVyJGFzY3llYXJzW2ldDQogICAgbW9udGggPC0gYXNjbGF5ZXIkYXNjbW9udGhzW2ldDQogICAgZGVwdGggPC0gYXNjbGF5ZXIkYXNjZGVwdGhzW2ldDQogICAgDQogICAgZm9yIChrIGluIDE6bGVuZ3RoKGFzY25hbWUpKXsNCiAgICAgICAgYXNjeWVhciA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDEpKQ0KICAgICAgICBhc2Ntb250aCA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDIpKQ0KICAgICAgICBhc2N2YXIgPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAzKSkNCiAgICAgICAgYXNjZGVwdGggPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCA0KSkNCiAgICAgICAgYXNjZGVwdGggPC0gZ3N1YigiLmFzYyIsICIiLCBhc2NkZXB0aCkNCiAgICAgICAgYXNjZmlsZSA8LSBhc2NwYXRoW2tdDQogICAgICAgIA0KDQogICAgICAgIGlmIChhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSB0ZW1wdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJHRlbXBfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gdGVtcHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHRlbXBfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzYWx2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkc2FsaW5pdHlfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc2FsdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkc2FsaW5pdHlfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBjaGx2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkY2hsX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGNobHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGNobF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG8ydmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJG8yX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG8ydmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbzJfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBtbHB2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG1scF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNzaHZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkc3NoX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbmFvc2FtcGxldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRuYW9fc2FtcGxlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGFtb3NhbXBsZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3NhbXBsZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBuYW9wcmV2dmFyKXsNCiAgICAgICAgICBhc2NsYXllciRuYW9fcHJldltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBhbW9wcmV2dmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fcHJldltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2N2YXIgPT0gbmFvd2ludGVydmFyKXsNCiAgICAgICAgICBhc2NsYXllciRuYW9fd2ludGVyW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY3ZhciA9PSBhbW93aW50ZXJ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb193aW50ZXJbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9DQogICAgfQ0KICB3cml0ZS5jc3YoYXNjbGF5ZXIsICIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0MjAwNy5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KfQ0KYGBgDQoNCmBgYHtyIGFzY2xpc3QgZm9yIDIwMDh9DQojISEhISEhICBDSEFOR0UgQVNDTkFNRSwgQVNDUEFUSCBBTkQgQ1NWIEZJTEUgTkFNRQ0KDQphc2NsYXllciA8LSBzdWJzZXQoYXNjbGF5ZXJhbGwsIGFzY3llYXJzID09IDIwMDgpDQoNCmFzY25hbWUgPC0gbGlzdC5maWxlcygiLi4vZGF0YS9lbnYvYXNjaWkvYXNjaWkyMDA4LyIsIHBhdHRlcm4gPSAiKi5hc2MiLCBmdWxsLm5hbWVzID0gRkFMU0UpICAgICMgdGhpcyBmb2xkZXIgY3VycmVudGx5IGNvbnRhaW5zIG90aGVyIGR1bW15IGZpbGVzLiBpdHMganVzdCBhIHRlc3QgdG8gYXV0b21hdGUgc3RhY2tzDQphc2NwYXRoIDwtIGxpc3QuZmlsZXMoIi4uL2RhdGEvZW52L2FzY2lpL2FzY2lpMjAwOC8iLCBwYXR0ZXJuID0gIiouYXNjIiwgZnVsbC5uYW1lcyA9IFRSVUUpICAgICMgdGhpcyBmb2xkZXIgY3VycmVudGx5IGNvbnRhaW5zIG90aGVyIGR1bW15IGZpbGVzLiBpdHMganVzdCBhIHRlc3QgdG8gYXV0b21hdGUgc3RhY2tzDQoNCnRlbXB2YXIgPC0gInRlbXAubmMiDQpjaGx2YXIgPC0gImNobC5uYyINCm8ydmFyIDwtICJvMi5uYyINCnNhbHZhciA8LSAic2FsaW5pdHkubmMiDQptbHB2YXIgPC0gIm1scC5uYyINCnNzaHZhciA8LSAic3NoLm5jIg0KbmFvc2FtcGxldmFyIDwtICJuYW9zYW1wbGUiDQphbW9zYW1wbGV2YXIgPC0gImFtb3NhbXBsZSINCm5hb3ByZXZ2YXIgPC0gIm5hb3ByZXYiDQphbW9wcmV2dmFyIDwtICJhbW9wcmV2Ig0KbmFvd2ludGVydmFyIDwtICJuYW93aW50ZXIiDQphbW93aW50ZXJ2YXIgPC0gImFtb3dpbnRlciINCnN1cmZhY2V2YXIgPC0gIjAuNTA1NzYiDQoNCmZvciAoaSBpbiAxOm5yb3coYXNjbGF5ZXIpKXsNCiAgICBwcmludChhc2NsYXllciRzdGFja25hbWVbaV0pDQogICAgeWVhciA8LSBhc2NsYXllciRhc2N5ZWFyc1tpXQ0KICAgIG1vbnRoIDwtIGFzY2xheWVyJGFzY21vbnRoc1tpXQ0KICAgIGRlcHRoIDwtIGFzY2xheWVyJGFzY2RlcHRoc1tpXQ0KICAgIA0KICAgIGZvciAoayBpbiAxOmxlbmd0aChhc2NuYW1lKSl7DQogICAgICAgIGFzY3llYXIgPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAxKSkNCiAgICAgICAgYXNjbW9udGggPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAyKSkNCiAgICAgICAgYXNjdmFyIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMykpDQogICAgICAgIGFzY2RlcHRoIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgNCkpDQogICAgICAgIGFzY2RlcHRoIDwtIGdzdWIoIi5hc2MiLCAiIiwgYXNjZGVwdGgpDQogICAgICAgIGFzY2ZpbGUgPC0gYXNjcGF0aFtrXQ0KICAgICAgICANCg0KICAgICAgICBpZiAoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gdGVtcHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciR0ZW1wX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHRlbXB2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciR0ZW1wX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc2FsdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJHNhbGluaXR5X2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNhbHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHNhbGluaXR5X3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gY2hsdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJGNobF9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBjaGx2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRjaGxfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBvMnZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRvMl9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBvMnZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG8yX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbWxwdmFyKXsNCiAgICAgICAgICBhc2NsYXllciRtbHBfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzc2h2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHNzaF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG5hb3NhbXBsZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3NhbXBsZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBhbW9zYW1wbGV2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb19zYW1wbGVbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbmFvcHJldnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3ByZXZbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gYW1vcHJldnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3ByZXZbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjdmFyID09IG5hb3dpbnRlcnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3dpbnRlcltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2N2YXIgPT0gYW1vd2ludGVydmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fd2ludGVyW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfQ0KICAgIH0NCiAgd3JpdGUuY3N2KGFzY2xheWVyLCAiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdDIwMDguY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCn0NCmBgYA0KDQpgYGB7ciBhc2NsaXN0IGZvciAyMDA5fQ0KIyEhISEhISAgQ0hBTkdFIEFTQ05BTUUsIEFTQ1BBVEggQU5EIENTViBGSUxFIE5BTUUNCg0KYXNjbGF5ZXIgPC0gc3Vic2V0KGFzY2xheWVyYWxsLCBhc2N5ZWFycyA9PSAyMDA5KQ0KDQphc2NuYW1lIDwtIGxpc3QuZmlsZXMoIi4uL2RhdGEvZW52L2FzY2lpL2FzY2lpMjAwOS8iLCBwYXR0ZXJuID0gIiouYXNjIiwgZnVsbC5uYW1lcyA9IEZBTFNFKSAgICAjIHRoaXMgZm9sZGVyIGN1cnJlbnRseSBjb250YWlucyBvdGhlciBkdW1teSBmaWxlcy4gaXRzIGp1c3QgYSB0ZXN0IHRvIGF1dG9tYXRlIHN0YWNrcw0KYXNjcGF0aCA8LSBsaXN0LmZpbGVzKCIuLi9kYXRhL2Vudi9hc2NpaS9hc2NpaTIwMDkvIiwgcGF0dGVybiA9ICIqLmFzYyIsIGZ1bGwubmFtZXMgPSBUUlVFKSAgICAjIHRoaXMgZm9sZGVyIGN1cnJlbnRseSBjb250YWlucyBvdGhlciBkdW1teSBmaWxlcy4gaXRzIGp1c3QgYSB0ZXN0IHRvIGF1dG9tYXRlIHN0YWNrcw0KDQp0ZW1wdmFyIDwtICJ0ZW1wLm5jIg0KY2hsdmFyIDwtICJjaGwubmMiDQpvMnZhciA8LSAibzIubmMiDQpzYWx2YXIgPC0gInNhbGluaXR5Lm5jIg0KbWxwdmFyIDwtICJtbHAubmMiDQpzc2h2YXIgPC0gInNzaC5uYyINCm5hb3NhbXBsZXZhciA8LSAibmFvc2FtcGxlIg0KYW1vc2FtcGxldmFyIDwtICJhbW9zYW1wbGUiDQpuYW9wcmV2dmFyIDwtICJuYW9wcmV2Ig0KYW1vcHJldnZhciA8LSAiYW1vcHJldiINCm5hb3dpbnRlcnZhciA8LSAibmFvd2ludGVyIg0KYW1vd2ludGVydmFyIDwtICJhbW93aW50ZXIiDQpzdXJmYWNldmFyIDwtICIwLjUwNTc2Ig0KDQpmb3IgKGkgaW4gMTpucm93KGFzY2xheWVyKSl7DQogICAgcHJpbnQoYXNjbGF5ZXIkc3RhY2tuYW1lW2ldKQ0KICAgIHllYXIgPC0gYXNjbGF5ZXIkYXNjeWVhcnNbaV0NCiAgICBtb250aCA8LSBhc2NsYXllciRhc2Ntb250aHNbaV0NCiAgICBkZXB0aCA8LSBhc2NsYXllciRhc2NkZXB0aHNbaV0NCiAgICANCiAgICBmb3IgKGsgaW4gMTpsZW5ndGgoYXNjbmFtZSkpew0KICAgICAgICBhc2N5ZWFyIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMSkpDQogICAgICAgIGFzY21vbnRoIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMikpDQogICAgICAgIGFzY3ZhciA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDMpKQ0KICAgICAgICBhc2NkZXB0aCA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDQpKQ0KICAgICAgICBhc2NkZXB0aCA8LSBnc3ViKCIuYXNjIiwgIiIsIGFzY2RlcHRoKQ0KICAgICAgICBhc2NmaWxlIDwtIGFzY3BhdGhba10NCiAgICAgICAgDQoNCiAgICAgICAgaWYgKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHRlbXB2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkdGVtcF9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSB0ZW1wdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkdGVtcF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNhbHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRzYWxpbml0eV9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzYWx2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRzYWxpbml0eV9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGNobHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRjaGxfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gY2hsdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkY2hsX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbzJ2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkbzJfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbzJ2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRvMl9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG1scHZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbWxwX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc3NodmFyKXsNCiAgICAgICAgICBhc2NsYXllciRzc2hfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBuYW9zYW1wbGV2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb19zYW1wbGVbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gYW1vc2FtcGxldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fc2FtcGxlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG5hb3ByZXZ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb19wcmV2W2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGFtb3ByZXZ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb19wcmV2W2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY3ZhciA9PSBuYW93aW50ZXJ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb193aW50ZXJbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjdmFyID09IGFtb3dpbnRlcnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3dpbnRlcltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0NCiAgICB9DQogIHdyaXRlLmNzdihhc2NsYXllciwgIi4uL2RhdGEvZW52L2FzY19sYXllcmxpc3QyMDA5LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp9DQpgYGANCg0KYGBge3IgYXNjbGlzdCBmb3IgMjAxMH0NCiMhISEhISEgIENIQU5HRSBBU0NOQU1FLCBBU0NQQVRIIEFORCBDU1YgRklMRSBOQU1FDQoNCmFzY2xheWVyIDwtIHN1YnNldChhc2NsYXllcmFsbCwgYXNjeWVhcnMgPT0gMjAxMCkNCg0KYXNjbmFtZSA8LSBsaXN0LmZpbGVzKCIuLi9kYXRhL2Vudi9hc2NpaS9hc2NpaTIwMTAvIiwgcGF0dGVybiA9ICIqLmFzYyIsIGZ1bGwubmFtZXMgPSBGQUxTRSkgICAgIyB0aGlzIGZvbGRlciBjdXJyZW50bHkgY29udGFpbnMgb3RoZXIgZHVtbXkgZmlsZXMuIGl0cyBqdXN0IGEgdGVzdCB0byBhdXRvbWF0ZSBzdGFja3MNCmFzY3BhdGggPC0gbGlzdC5maWxlcygiLi4vZGF0YS9lbnYvYXNjaWkvYXNjaWkyMDEwLyIsIHBhdHRlcm4gPSAiKi5hc2MiLCBmdWxsLm5hbWVzID0gVFJVRSkgICAgIyB0aGlzIGZvbGRlciBjdXJyZW50bHkgY29udGFpbnMgb3RoZXIgZHVtbXkgZmlsZXMuIGl0cyBqdXN0IGEgdGVzdCB0byBhdXRvbWF0ZSBzdGFja3MNCg0KdGVtcHZhciA8LSAidGVtcC5uYyINCmNobHZhciA8LSAiY2hsLm5jIg0KbzJ2YXIgPC0gIm8yLm5jIg0Kc2FsdmFyIDwtICJzYWxpbml0eS5uYyINCm1scHZhciA8LSAibWxwLm5jIg0Kc3NodmFyIDwtICJzc2gubmMiDQpuYW9zYW1wbGV2YXIgPC0gIm5hb3NhbXBsZSINCmFtb3NhbXBsZXZhciA8LSAiYW1vc2FtcGxlIg0KbmFvcHJldnZhciA8LSAibmFvcHJldiINCmFtb3ByZXZ2YXIgPC0gImFtb3ByZXYiDQpuYW93aW50ZXJ2YXIgPC0gIm5hb3dpbnRlciINCmFtb3dpbnRlcnZhciA8LSAiYW1vd2ludGVyIg0Kc3VyZmFjZXZhciA8LSAiMC41MDU3NiINCg0KZm9yIChpIGluIDE6bnJvdyhhc2NsYXllcikpew0KICAgIHByaW50KGFzY2xheWVyJHN0YWNrbmFtZVtpXSkNCiAgICB5ZWFyIDwtIGFzY2xheWVyJGFzY3llYXJzW2ldDQogICAgbW9udGggPC0gYXNjbGF5ZXIkYXNjbW9udGhzW2ldDQogICAgZGVwdGggPC0gYXNjbGF5ZXIkYXNjZGVwdGhzW2ldDQogICAgDQogICAgZm9yIChrIGluIDE6bGVuZ3RoKGFzY25hbWUpKXsNCiAgICAgICAgYXNjeWVhciA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDEpKQ0KICAgICAgICBhc2Ntb250aCA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDIpKQ0KICAgICAgICBhc2N2YXIgPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAzKSkNCiAgICAgICAgYXNjZGVwdGggPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCA0KSkNCiAgICAgICAgYXNjZGVwdGggPC0gZ3N1YigiLmFzYyIsICIiLCBhc2NkZXB0aCkNCiAgICAgICAgYXNjZmlsZSA8LSBhc2NwYXRoW2tdDQogICAgICAgIA0KDQogICAgICAgIGlmIChhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSB0ZW1wdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJHRlbXBfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gdGVtcHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHRlbXBfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzYWx2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkc2FsaW5pdHlfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc2FsdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkc2FsaW5pdHlfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBjaGx2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkY2hsX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGNobHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGNobF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG8ydmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJG8yX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG8ydmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbzJfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBtbHB2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG1scF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNzaHZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkc3NoX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbmFvc2FtcGxldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRuYW9fc2FtcGxlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGFtb3NhbXBsZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3NhbXBsZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBuYW9wcmV2dmFyKXsNCiAgICAgICAgICBhc2NsYXllciRuYW9fcHJldltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBhbW9wcmV2dmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fcHJldltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2N2YXIgPT0gbmFvd2ludGVydmFyKXsNCiAgICAgICAgICBhc2NsYXllciRuYW9fd2ludGVyW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY3ZhciA9PSBhbW93aW50ZXJ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb193aW50ZXJbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9DQogICAgfQ0KICB3cml0ZS5jc3YoYXNjbGF5ZXIsICIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0MjAxMC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KfQ0KYGBgDQoNCmBgYHtyIGFzY2xpc3QgZm9yIDIwMTF9DQojISEhISEhICBDSEFOR0UgQVNDTkFNRSwgQVNDUEFUSCBBTkQgQ1NWIEZJTEUgTkFNRQ0KDQphc2NsYXllciA8LSBzdWJzZXQoYXNjbGF5ZXJhbGwsIGFzY3llYXJzID09IDIwMTEpDQoNCmFzY25hbWUgPC0gbGlzdC5maWxlcygiLi4vZGF0YS9lbnYvYXNjaWkvYXNjaWkyMDExLyIsIHBhdHRlcm4gPSAiKi5hc2MiLCBmdWxsLm5hbWVzID0gRkFMU0UpICAgICMgdGhpcyBmb2xkZXIgY3VycmVudGx5IGNvbnRhaW5zIG90aGVyIGR1bW15IGZpbGVzLiBpdHMganVzdCBhIHRlc3QgdG8gYXV0b21hdGUgc3RhY2tzDQphc2NwYXRoIDwtIGxpc3QuZmlsZXMoIi4uL2RhdGEvZW52L2FzY2lpL2FzY2lpMjAxMS8iLCBwYXR0ZXJuID0gIiouYXNjIiwgZnVsbC5uYW1lcyA9IFRSVUUpICAgICMgdGhpcyBmb2xkZXIgY3VycmVudGx5IGNvbnRhaW5zIG90aGVyIGR1bW15IGZpbGVzLiBpdHMganVzdCBhIHRlc3QgdG8gYXV0b21hdGUgc3RhY2tzDQoNCnRlbXB2YXIgPC0gInRlbXAubmMiDQpjaGx2YXIgPC0gImNobC5uYyINCm8ydmFyIDwtICJvMi5uYyINCnNhbHZhciA8LSAic2FsaW5pdHkubmMiDQptbHB2YXIgPC0gIm1scC5uYyINCnNzaHZhciA8LSAic3NoLm5jIg0KbmFvc2FtcGxldmFyIDwtICJuYW9zYW1wbGUiDQphbW9zYW1wbGV2YXIgPC0gImFtb3NhbXBsZSINCm5hb3ByZXZ2YXIgPC0gIm5hb3ByZXYiDQphbW9wcmV2dmFyIDwtICJhbW9wcmV2Ig0KbmFvd2ludGVydmFyIDwtICJuYW93aW50ZXIiDQphbW93aW50ZXJ2YXIgPC0gImFtb3dpbnRlciINCnN1cmZhY2V2YXIgPC0gIjAuNTA1NzYiDQoNCmZvciAoaSBpbiAxOm5yb3coYXNjbGF5ZXIpKXsNCiAgICBwcmludChhc2NsYXllciRzdGFja25hbWVbaV0pDQogICAgeWVhciA8LSBhc2NsYXllciRhc2N5ZWFyc1tpXQ0KICAgIG1vbnRoIDwtIGFzY2xheWVyJGFzY21vbnRoc1tpXQ0KICAgIGRlcHRoIDwtIGFzY2xheWVyJGFzY2RlcHRoc1tpXQ0KICAgIA0KICAgIGZvciAoayBpbiAxOmxlbmd0aChhc2NuYW1lKSl7DQogICAgICAgIGFzY3llYXIgPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAxKSkNCiAgICAgICAgYXNjbW9udGggPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAyKSkNCiAgICAgICAgYXNjdmFyIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMykpDQogICAgICAgIGFzY2RlcHRoIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgNCkpDQogICAgICAgIGFzY2RlcHRoIDwtIGdzdWIoIi5hc2MiLCAiIiwgYXNjZGVwdGgpDQogICAgICAgIGFzY2ZpbGUgPC0gYXNjcGF0aFtrXQ0KICAgICAgICANCg0KICAgICAgICBpZiAoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gdGVtcHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciR0ZW1wX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHRlbXB2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciR0ZW1wX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc2FsdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJHNhbGluaXR5X2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNhbHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHNhbGluaXR5X3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gY2hsdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJGNobF9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBjaGx2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRjaGxfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBvMnZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRvMl9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBvMnZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG8yX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbWxwdmFyKXsNCiAgICAgICAgICBhc2NsYXllciRtbHBfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzc2h2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHNzaF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG5hb3NhbXBsZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3NhbXBsZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBhbW9zYW1wbGV2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb19zYW1wbGVbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbmFvcHJldnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3ByZXZbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gYW1vcHJldnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3ByZXZbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjdmFyID09IG5hb3dpbnRlcnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3dpbnRlcltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2N2YXIgPT0gYW1vd2ludGVydmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fd2ludGVyW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfQ0KICAgIH0NCiAgd3JpdGUuY3N2KGFzY2xheWVyLCAiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdDIwMTEuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCn0NCmBgYA0KDQpgYGB7ciBhc2NsaXN0IGZvciAyMDEyfQ0KIyEhISEhISAgQ0hBTkdFIEFTQ05BTUUsIEFTQ1BBVEggQU5EIENTViBGSUxFIE5BTUUNCg0KYXNjbGF5ZXIgPC0gc3Vic2V0KGFzY2xheWVyYWxsLCBhc2N5ZWFycyA9PSAyMDEyKQ0KDQphc2NuYW1lIDwtIGxpc3QuZmlsZXMoIi4uL2RhdGEvZW52L2FzY2lpL2FzY2lpMjAxMi8iLCBwYXR0ZXJuID0gIiouYXNjIiwgZnVsbC5uYW1lcyA9IEZBTFNFKSAgICAjIHRoaXMgZm9sZGVyIGN1cnJlbnRseSBjb250YWlucyBvdGhlciBkdW1teSBmaWxlcy4gaXRzIGp1c3QgYSB0ZXN0IHRvIGF1dG9tYXRlIHN0YWNrcw0KYXNjcGF0aCA8LSBsaXN0LmZpbGVzKCIuLi9kYXRhL2Vudi9hc2NpaS9hc2NpaTIwMTIvIiwgcGF0dGVybiA9ICIqLmFzYyIsIGZ1bGwubmFtZXMgPSBUUlVFKSAgICAjIHRoaXMgZm9sZGVyIGN1cnJlbnRseSBjb250YWlucyBvdGhlciBkdW1teSBmaWxlcy4gaXRzIGp1c3QgYSB0ZXN0IHRvIGF1dG9tYXRlIHN0YWNrcw0KDQp0ZW1wdmFyIDwtICJ0ZW1wLm5jIg0KY2hsdmFyIDwtICJjaGwubmMiDQpvMnZhciA8LSAibzIubmMiDQpzYWx2YXIgPC0gInNhbGluaXR5Lm5jIg0KbWxwdmFyIDwtICJtbHAubmMiDQpzc2h2YXIgPC0gInNzaC5uYyINCm5hb3NhbXBsZXZhciA8LSAibmFvc2FtcGxlIg0KYW1vc2FtcGxldmFyIDwtICJhbW9zYW1wbGUiDQpuYW9wcmV2dmFyIDwtICJuYW9wcmV2Ig0KYW1vcHJldnZhciA8LSAiYW1vcHJldiINCm5hb3dpbnRlcnZhciA8LSAibmFvd2ludGVyIg0KYW1vd2ludGVydmFyIDwtICJhbW93aW50ZXIiDQpzdXJmYWNldmFyIDwtICIwLjUwNTc2Ig0KDQpmb3IgKGkgaW4gMTpucm93KGFzY2xheWVyKSl7DQogICAgcHJpbnQoYXNjbGF5ZXIkc3RhY2tuYW1lW2ldKQ0KICAgIHllYXIgPC0gYXNjbGF5ZXIkYXNjeWVhcnNbaV0NCiAgICBtb250aCA8LSBhc2NsYXllciRhc2Ntb250aHNbaV0NCiAgICBkZXB0aCA8LSBhc2NsYXllciRhc2NkZXB0aHNbaV0NCiAgICANCiAgICBmb3IgKGsgaW4gMTpsZW5ndGgoYXNjbmFtZSkpew0KICAgICAgICBhc2N5ZWFyIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMSkpDQogICAgICAgIGFzY21vbnRoIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMikpDQogICAgICAgIGFzY3ZhciA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDMpKQ0KICAgICAgICBhc2NkZXB0aCA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDQpKQ0KICAgICAgICBhc2NkZXB0aCA8LSBnc3ViKCIuYXNjIiwgIiIsIGFzY2RlcHRoKQ0KICAgICAgICBhc2NmaWxlIDwtIGFzY3BhdGhba10NCiAgICAgICAgDQoNCiAgICAgICAgaWYgKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHRlbXB2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkdGVtcF9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSB0ZW1wdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkdGVtcF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNhbHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRzYWxpbml0eV9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzYWx2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRzYWxpbml0eV9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGNobHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRjaGxfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gY2hsdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkY2hsX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbzJ2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkbzJfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbzJ2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRvMl9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG1scHZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbWxwX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc3NodmFyKXsNCiAgICAgICAgICBhc2NsYXllciRzc2hfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBuYW9zYW1wbGV2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb19zYW1wbGVbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gYW1vc2FtcGxldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fc2FtcGxlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG5hb3ByZXZ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb19wcmV2W2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGFtb3ByZXZ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb19wcmV2W2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY3ZhciA9PSBuYW93aW50ZXJ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb193aW50ZXJbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjdmFyID09IGFtb3dpbnRlcnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3dpbnRlcltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0NCiAgICB9DQogIHdyaXRlLmNzdihhc2NsYXllciwgIi4uL2RhdGEvZW52L2FzY19sYXllcmxpc3QyMDEyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp9DQpgYGANCg0KYGBge3IgYXNjbGlzdCBmb3IgMjAxM30NCiMhISEhISEgIENIQU5HRSBBU0NOQU1FLCBBU0NQQVRIIEFORCBDU1YgRklMRSBOQU1FDQoNCmFzY2xheWVyIDwtIHN1YnNldChhc2NsYXllcmFsbCwgYXNjeWVhcnMgPT0gMjAxMykNCg0KYXNjbmFtZSA8LSBsaXN0LmZpbGVzKCIuLi9kYXRhL2Vudi9hc2NpaS9hc2NpaTIwMTMvIiwgcGF0dGVybiA9ICIqLmFzYyIsIGZ1bGwubmFtZXMgPSBGQUxTRSkgICAgIyB0aGlzIGZvbGRlciBjdXJyZW50bHkgY29udGFpbnMgb3RoZXIgZHVtbXkgZmlsZXMuIGl0cyBqdXN0IGEgdGVzdCB0byBhdXRvbWF0ZSBzdGFja3MNCmFzY3BhdGggPC0gbGlzdC5maWxlcygiLi4vZGF0YS9lbnYvYXNjaWkvYXNjaWkyMDEzLyIsIHBhdHRlcm4gPSAiKi5hc2MiLCBmdWxsLm5hbWVzID0gVFJVRSkgICAgIyB0aGlzIGZvbGRlciBjdXJyZW50bHkgY29udGFpbnMgb3RoZXIgZHVtbXkgZmlsZXMuIGl0cyBqdXN0IGEgdGVzdCB0byBhdXRvbWF0ZSBzdGFja3MNCg0KdGVtcHZhciA8LSAidGVtcC5uYyINCmNobHZhciA8LSAiY2hsLm5jIg0KbzJ2YXIgPC0gIm8yLm5jIg0Kc2FsdmFyIDwtICJzYWxpbml0eS5uYyINCm1scHZhciA8LSAibWxwLm5jIg0Kc3NodmFyIDwtICJzc2gubmMiDQpuYW9zYW1wbGV2YXIgPC0gIm5hb3NhbXBsZSINCmFtb3NhbXBsZXZhciA8LSAiYW1vc2FtcGxlIg0KbmFvcHJldnZhciA8LSAibmFvcHJldiINCmFtb3ByZXZ2YXIgPC0gImFtb3ByZXYiDQpuYW93aW50ZXJ2YXIgPC0gIm5hb3dpbnRlciINCmFtb3dpbnRlcnZhciA8LSAiYW1vd2ludGVyIg0Kc3VyZmFjZXZhciA8LSAiMC41MDU3NiINCg0KZm9yIChpIGluIDE6bnJvdyhhc2NsYXllcikpew0KICAgIHByaW50KGFzY2xheWVyJHN0YWNrbmFtZVtpXSkNCiAgICB5ZWFyIDwtIGFzY2xheWVyJGFzY3llYXJzW2ldDQogICAgbW9udGggPC0gYXNjbGF5ZXIkYXNjbW9udGhzW2ldDQogICAgZGVwdGggPC0gYXNjbGF5ZXIkYXNjZGVwdGhzW2ldDQogICAgDQogICAgZm9yIChrIGluIDE6bGVuZ3RoKGFzY25hbWUpKXsNCiAgICAgICAgYXNjeWVhciA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDEpKQ0KICAgICAgICBhc2Ntb250aCA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDIpKQ0KICAgICAgICBhc2N2YXIgPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAzKSkNCiAgICAgICAgYXNjZGVwdGggPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCA0KSkNCiAgICAgICAgYXNjZGVwdGggPC0gZ3N1YigiLmFzYyIsICIiLCBhc2NkZXB0aCkNCiAgICAgICAgYXNjZmlsZSA8LSBhc2NwYXRoW2tdDQogICAgICAgIA0KDQogICAgICAgIGlmIChhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSB0ZW1wdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJHRlbXBfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gdGVtcHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHRlbXBfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzYWx2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkc2FsaW5pdHlfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc2FsdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkc2FsaW5pdHlfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBjaGx2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkY2hsX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGNobHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGNobF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG8ydmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJG8yX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG8ydmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbzJfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBtbHB2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG1scF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNzaHZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkc3NoX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbmFvc2FtcGxldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRuYW9fc2FtcGxlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGFtb3NhbXBsZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3NhbXBsZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBuYW9wcmV2dmFyKXsNCiAgICAgICAgICBhc2NsYXllciRuYW9fcHJldltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBhbW9wcmV2dmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fcHJldltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2N2YXIgPT0gbmFvd2ludGVydmFyKXsNCiAgICAgICAgICBhc2NsYXllciRuYW9fd2ludGVyW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY3ZhciA9PSBhbW93aW50ZXJ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb193aW50ZXJbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9DQogICAgfQ0KICB3cml0ZS5jc3YoYXNjbGF5ZXIsICIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0MjAxMy5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KfQ0KYGBgDQoNCmBgYHtyIGFzY2xpc3QgZm9yIDIwMTR9DQojISEhISEhICBDSEFOR0UgQVNDTkFNRSwgQVNDUEFUSCBBTkQgQ1NWIEZJTEUgTkFNRQ0KDQphc2NsYXllciA8LSBzdWJzZXQoYXNjbGF5ZXJhbGwsIGFzY3llYXJzID09IDIwMTQpDQoNCmFzY25hbWUgPC0gbGlzdC5maWxlcygiLi4vZGF0YS9lbnYvYXNjaWkvYXNjaWkyMDE0LyIsIHBhdHRlcm4gPSAiKi5hc2MiLCBmdWxsLm5hbWVzID0gRkFMU0UpICAgICMgdGhpcyBmb2xkZXIgY3VycmVudGx5IGNvbnRhaW5zIG90aGVyIGR1bW15IGZpbGVzLiBpdHMganVzdCBhIHRlc3QgdG8gYXV0b21hdGUgc3RhY2tzDQphc2NwYXRoIDwtIGxpc3QuZmlsZXMoIi4uL2RhdGEvZW52L2FzY2lpL2FzY2lpMjAxNC8iLCBwYXR0ZXJuID0gIiouYXNjIiwgZnVsbC5uYW1lcyA9IFRSVUUpICAgICMgdGhpcyBmb2xkZXIgY3VycmVudGx5IGNvbnRhaW5zIG90aGVyIGR1bW15IGZpbGVzLiBpdHMganVzdCBhIHRlc3QgdG8gYXV0b21hdGUgc3RhY2tzDQoNCnRlbXB2YXIgPC0gInRlbXAubmMiDQpjaGx2YXIgPC0gImNobC5uYyINCm8ydmFyIDwtICJvMi5uYyINCnNhbHZhciA8LSAic2FsaW5pdHkubmMiDQptbHB2YXIgPC0gIm1scC5uYyINCnNzaHZhciA8LSAic3NoLm5jIg0KbmFvc2FtcGxldmFyIDwtICJuYW9zYW1wbGUiDQphbW9zYW1wbGV2YXIgPC0gImFtb3NhbXBsZSINCm5hb3ByZXZ2YXIgPC0gIm5hb3ByZXYiDQphbW9wcmV2dmFyIDwtICJhbW9wcmV2Ig0KbmFvd2ludGVydmFyIDwtICJuYW93aW50ZXIiDQphbW93aW50ZXJ2YXIgPC0gImFtb3dpbnRlciINCnN1cmZhY2V2YXIgPC0gIjAuNTA1NzYiDQoNCmZvciAoaSBpbiAxOm5yb3coYXNjbGF5ZXIpKXsNCiAgICBwcmludChhc2NsYXllciRzdGFja25hbWVbaV0pDQogICAgeWVhciA8LSBhc2NsYXllciRhc2N5ZWFyc1tpXQ0KICAgIG1vbnRoIDwtIGFzY2xheWVyJGFzY21vbnRoc1tpXQ0KICAgIGRlcHRoIDwtIGFzY2xheWVyJGFzY2RlcHRoc1tpXQ0KICAgIA0KICAgIGZvciAoayBpbiAxOmxlbmd0aChhc2NuYW1lKSl7DQogICAgICAgIGFzY3llYXIgPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAxKSkNCiAgICAgICAgYXNjbW9udGggPC0gKHNhcHBseShzdHJzcGxpdChhc2NuYW1lW2tdLCAiXyIpLCAiW1siLCAyKSkNCiAgICAgICAgYXNjdmFyIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMykpDQogICAgICAgIGFzY2RlcHRoIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgNCkpDQogICAgICAgIGFzY2RlcHRoIDwtIGdzdWIoIi5hc2MiLCAiIiwgYXNjZGVwdGgpDQogICAgICAgIGFzY2ZpbGUgPC0gYXNjcGF0aFtrXQ0KICAgICAgICANCg0KICAgICAgICBpZiAoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gdGVtcHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciR0ZW1wX2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHRlbXB2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciR0ZW1wX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc2FsdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJHNhbGluaXR5X2RlcHRoW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNhbHZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHNhbGluaXR5X3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gY2hsdmFyICYgYXNjZGVwdGggPT0gZGVwdGgpew0KICAgICAgICAgIGFzY2xheWVyJGNobF9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBjaGx2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRjaGxfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBvMnZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRvMl9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBvMnZhciAmIGFzY2RlcHRoID09IHN1cmZhY2V2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG8yX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbWxwdmFyKXsNCiAgICAgICAgICBhc2NsYXllciRtbHBfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzc2h2YXIpew0KICAgICAgICAgIGFzY2xheWVyJHNzaF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG5hb3NhbXBsZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3NhbXBsZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBhbW9zYW1wbGV2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb19zYW1wbGVbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbmFvcHJldnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3ByZXZbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gYW1vcHJldnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3ByZXZbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjdmFyID09IG5hb3dpbnRlcnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbmFvX3dpbnRlcltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2N2YXIgPT0gYW1vd2ludGVydmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fd2ludGVyW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfQ0KICAgIH0NCiAgd3JpdGUuY3N2KGFzY2xheWVyLCAiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdDIwMTQuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCn0NCmBgYA0KDQpgYGB7ciBhc2NsaXN0IGZvciAyMDE1fQ0KIyEhISEhISAgQ0hBTkdFIEFTQ05BTUUsIEFTQ1BBVEggQU5EIENTViBGSUxFIE5BTUUNCg0KYXNjbGF5ZXIgPC0gc3Vic2V0KGFzY2xheWVyYWxsLCBhc2N5ZWFycyA9PSAyMDE1KQ0KDQphc2NuYW1lIDwtIGxpc3QuZmlsZXMoIi4uL2RhdGEvZW52L2FzY2lpL2FzY2lpMjAxNS8iLCBwYXR0ZXJuID0gIiouYXNjIiwgZnVsbC5uYW1lcyA9IEZBTFNFKSAgICAjIHRoaXMgZm9sZGVyIGN1cnJlbnRseSBjb250YWlucyBvdGhlciBkdW1teSBmaWxlcy4gaXRzIGp1c3QgYSB0ZXN0IHRvIGF1dG9tYXRlIHN0YWNrcw0KYXNjcGF0aCA8LSBsaXN0LmZpbGVzKCIuLi9kYXRhL2Vudi9hc2NpaS9hc2NpaTIwMTUvIiwgcGF0dGVybiA9ICIqLmFzYyIsIGZ1bGwubmFtZXMgPSBUUlVFKSAgICAjIHRoaXMgZm9sZGVyIGN1cnJlbnRseSBjb250YWlucyBvdGhlciBkdW1teSBmaWxlcy4gaXRzIGp1c3QgYSB0ZXN0IHRvIGF1dG9tYXRlIHN0YWNrcw0KDQp0ZW1wdmFyIDwtICJ0ZW1wLm5jIg0KY2hsdmFyIDwtICJjaGwubmMiDQpvMnZhciA8LSAibzIubmMiDQpzYWx2YXIgPC0gInNhbGluaXR5Lm5jIg0KbWxwdmFyIDwtICJtbHAubmMiDQpzc2h2YXIgPC0gInNzaC5uYyINCm5hb3NhbXBsZXZhciA8LSAibmFvc2FtcGxlIg0KYW1vc2FtcGxldmFyIDwtICJhbW9zYW1wbGUiDQpuYW9wcmV2dmFyIDwtICJuYW9wcmV2Ig0KYW1vcHJldnZhciA8LSAiYW1vcHJldiINCm5hb3dpbnRlcnZhciA8LSAibmFvd2ludGVyIg0KYW1vd2ludGVydmFyIDwtICJhbW93aW50ZXIiDQpzdXJmYWNldmFyIDwtICIwLjUwNTc2Ig0KDQpmb3IgKGkgaW4gMTpucm93KGFzY2xheWVyKSl7DQogICAgcHJpbnQoYXNjbGF5ZXIkc3RhY2tuYW1lW2ldKQ0KICAgIHllYXIgPC0gYXNjbGF5ZXIkYXNjeWVhcnNbaV0NCiAgICBtb250aCA8LSBhc2NsYXllciRhc2Ntb250aHNbaV0NCiAgICBkZXB0aCA8LSBhc2NsYXllciRhc2NkZXB0aHNbaV0NCiAgICANCiAgICBmb3IgKGsgaW4gMTpsZW5ndGgoYXNjbmFtZSkpew0KICAgICAgICBhc2N5ZWFyIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMSkpDQogICAgICAgIGFzY21vbnRoIDwtIChzYXBwbHkoc3Ryc3BsaXQoYXNjbmFtZVtrXSwgIl8iKSwgIltbIiwgMikpDQogICAgICAgIGFzY3ZhciA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDMpKQ0KICAgICAgICBhc2NkZXB0aCA8LSAoc2FwcGx5KHN0cnNwbGl0KGFzY25hbWVba10sICJfIiksICJbWyIsIDQpKQ0KICAgICAgICBhc2NkZXB0aCA8LSBnc3ViKCIuYXNjIiwgIiIsIGFzY2RlcHRoKQ0KICAgICAgICBhc2NmaWxlIDwtIGFzY3BhdGhba10NCiAgICAgICAgDQoNCiAgICAgICAgaWYgKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHRlbXB2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkdGVtcF9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSB0ZW1wdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkdGVtcF9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IHNhbHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRzYWxpbml0eV9kZXB0aFtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBzYWx2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRzYWxpbml0eV9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGNobHZhciAmIGFzY2RlcHRoID09IGRlcHRoKXsNCiAgICAgICAgICBhc2NsYXllciRjaGxfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gY2hsdmFyICYgYXNjZGVwdGggPT0gc3VyZmFjZXZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkY2hsX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbzJ2YXIgJiBhc2NkZXB0aCA9PSBkZXB0aCl7DQogICAgICAgICAgYXNjbGF5ZXIkbzJfZGVwdGhbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gbzJ2YXIgJiBhc2NkZXB0aCA9PSBzdXJmYWNldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRvMl9zdXJmYWNlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG1scHZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkbWxwX3N1cmZhY2VbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gc3NodmFyKXsNCiAgICAgICAgICBhc2NsYXllciRzc2hfc3VyZmFjZVtpXSA8LSBhc2NmaWxlDQogICAgICAgIH0gZWxzZSBpZihhc2N5ZWFyID09IHllYXIgJiBhc2Ntb250aCA9PSBtb250aCAmIGFzY3ZhciA9PSBuYW9zYW1wbGV2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb19zYW1wbGVbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjbW9udGggPT0gbW9udGggJiBhc2N2YXIgPT0gYW1vc2FtcGxldmFyKXsNCiAgICAgICAgICBhc2NsYXllciRhbW9fc2FtcGxlW2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IG5hb3ByZXZ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb19wcmV2W2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY21vbnRoID09IG1vbnRoICYgYXNjdmFyID09IGFtb3ByZXZ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJGFtb19wcmV2W2ldIDwtIGFzY2ZpbGUNCiAgICAgICAgfSBlbHNlIGlmKGFzY3llYXIgPT0geWVhciAmIGFzY3ZhciA9PSBuYW93aW50ZXJ2YXIpew0KICAgICAgICAgIGFzY2xheWVyJG5hb193aW50ZXJbaV0gPC0gYXNjZmlsZQ0KICAgICAgICB9IGVsc2UgaWYoYXNjeWVhciA9PSB5ZWFyICYgYXNjdmFyID09IGFtb3dpbnRlcnZhcil7DQogICAgICAgICAgYXNjbGF5ZXIkYW1vX3dpbnRlcltpXSA8LSBhc2NmaWxlDQogICAgICAgIH0NCiAgICB9DQogIHdyaXRlLmNzdihhc2NsYXllciwgIi4uL2RhdGEvZW52L2FzY19sYXllcmxpc3QyMDE1LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp9DQpgYGANCg0KDQoNCml0IG1heSBiZSBiZXR0ZXIgdG8gaGF2ZSBhc2NpaSBsaXN0cyBwZXIgbW9udGggKHNpbmNlIG1vZGVscyBhcmUgcGVyIG1vbnRoKQ0KDQpgYGB7cn0NCmExOTk4IDwtIHJlYWQuY3N2KCIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0MTk5OC5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KYTE5OTkgPC0gcmVhZC5jc3YoIi4uL2RhdGEvZW52L2FzY19sYXllcmxpc3QxOTk5LmNzdiIsIGhlYWRlciA9IFRSVUUpDQphMjAwMCA8LSByZWFkLmNzdigiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdDIwMDAuY3N2IiwgaGVhZGVyID0gVFJVRSkNCmEyMDAxIDwtIHJlYWQuY3N2KCIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0MjAwMS5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KYTIwMDIgPC0gcmVhZC5jc3YoIi4uL2RhdGEvZW52L2FzY19sYXllcmxpc3QyMDAyLmNzdiIsIGhlYWRlciA9IFRSVUUpDQphMjAwMyA8LSByZWFkLmNzdigiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdDIwMDMuY3N2IiwgaGVhZGVyID0gVFJVRSkNCmEyMDA0IDwtIHJlYWQuY3N2KCIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0MjAwNC5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KYTIwMDUgPC0gcmVhZC5jc3YoIi4uL2RhdGEvZW52L2FzY19sYXllcmxpc3QyMDA1LmNzdiIsIGhlYWRlciA9IFRSVUUpDQphMjAwNiA8LSByZWFkLmNzdigiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdDIwMDYuY3N2IiwgaGVhZGVyID0gVFJVRSkNCmEyMDA3IDwtIHJlYWQuY3N2KCIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0MjAwNy5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KYTIwMDggPC0gcmVhZC5jc3YoIi4uL2RhdGEvZW52L2FzY19sYXllcmxpc3QyMDA4LmNzdiIsIGhlYWRlciA9IFRSVUUpDQphMjAwOSA8LSByZWFkLmNzdigiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdDIwMDkuY3N2IiwgaGVhZGVyID0gVFJVRSkNCmEyMDEwIDwtIHJlYWQuY3N2KCIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0MjAxMC5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KYTIwMTEgPC0gcmVhZC5jc3YoIi4uL2RhdGEvZW52L2FzY19sYXllcmxpc3QyMDExLmNzdiIsIGhlYWRlciA9IFRSVUUpDQphMjAxMiA8LSByZWFkLmNzdigiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdDIwMTIuY3N2IiwgaGVhZGVyID0gVFJVRSkNCmEyMDEzIDwtIHJlYWQuY3N2KCIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0MjAxMy5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KYTIwMTQgPC0gcmVhZC5jc3YoIi4uL2RhdGEvZW52L2FzY19sYXllcmxpc3QyMDE0LmNzdiIsIGhlYWRlciA9IFRSVUUpDQphMjAxNSA8LSByZWFkLmNzdigiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdDIwMTUuY3N2IiwgaGVhZGVyID0gVFJVRSkNCg0KYXMgPC0gcmJpbmQoYTE5OTgsIGExOTk5LCBhMjAwMCwgYTIwMDEsIGEyMDAyLCBhMjAwMywgYTIwMDQsIGEyMDA1LCBhMjAwNiwgYTIwMDcsIGEyMDA4LCBhMjAwOSwgYTIwMTAsIGEyMDExLCBhMjAxMiwgYTIwMTMsIGEyMDE0LCBhMjAxNSkNCg0KYXNtIDwtIHNwbGl0KGFzLCBhcyRhc2Ntb250aHMpDQp3cml0ZS5jc3YoYXNtJGAxYCwgIi4uL2RhdGEvZW52L2FzY19sYXllcmxpc3RqYW4uY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCndyaXRlLmNzdihhc20kYDJgLCAiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdGZlYi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0Kd3JpdGUuY3N2KGFzbSRgM2AsICIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0bWFyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp3cml0ZS5jc3YoYXNtJGA0YCwgIi4uL2RhdGEvZW52L2FzY19sYXllcmxpc3RhcHIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCndyaXRlLmNzdihhc20kYDVgLCAiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdG1heS5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0Kd3JpdGUuY3N2KGFzbSRgNmAsICIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0anVuLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp3cml0ZS5jc3YoYXNtJGA3YCwgIi4uL2RhdGEvZW52L2FzY19sYXllcmxpc3RqdWwuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCndyaXRlLmNzdihhc20kYDhgLCAiLi4vZGF0YS9lbnYvYXNjX2xheWVybGlzdGF1Zy5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0Kd3JpdGUuY3N2KGFzbSRgOWAsICIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0c2VwLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp3cml0ZS5jc3YoYXNtJGAxMGAsICIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0b2N0LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp3cml0ZS5jc3YoYXNtJGAxMWAsICIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0bm92LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp3cml0ZS5jc3YoYXNtJGAxMmAsICIuLi9kYXRhL2Vudi9hc2NfbGF5ZXJsaXN0ZGVjLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQpgYGANCg0K